Создание трехмерной сферы в Opengl с использованием Visual C ++

Некоторая дополнительная информация, которую кто-то мог присоединить к более раннему сообщению Jason Pratt на Alice... а именно, Повествующий вариант Alice.

, Хотя исследование представило целевых школьниц, можно найти отчет записанный Caitlin Kelleher интересный.

27
задан Mat 26 May 2013 в 15:33
поделиться

3 ответа

Вот код:

glPushMatrix();
glTranslatef(18,2,0);
glRotatef(angle, 0, 0, 0.7);
glColor3ub(0,255,255);
glutWireSphere(3,10,10);
glPopMatrix();
3
ответ дан 28 November 2019 в 04:03
поделиться

Мне нравится ответ монеты. Это просто понять и работает с треугольниками. Однако индексы его программы иногда выходят за границы. Поэтому я публикую здесь его код с двумя небольшими исправлениями:

inline void push_indices(vector<GLushort>& indices, int sectors, int r, int s) {
    int curRow = r * sectors;
    int nextRow = (r+1) * sectors;
    int nextS = (s+1) % sectors;

    indices.push_back(curRow + s);
    indices.push_back(nextRow + s);
    indices.push_back(nextRow + nextS);

    indices.push_back(curRow + s);
    indices.push_back(nextRow + nextS);
    indices.push_back(curRow + nextS);
}

void createSphere(vector<vec3>& vertices, vector<GLushort>& indices, vector<vec2>& texcoords,
                  float radius, unsigned int rings, unsigned int sectors)
{
    float const R = 1./(float)(rings-1);
    float const S = 1./(float)(sectors-1);

    for(int r = 0; r < rings; ++r) {
        for(int s = 0; s < sectors; ++s) {
            float const y = sin( -M_PI_2 + M_PI * r * R );
            float const x = cos(2*M_PI * s * S) * sin( M_PI * r * R );
            float const z = sin(2*M_PI * s * S) * sin( M_PI * r * R );

            texcoords.push_back(vec2(s*S, r*R));
            vertices.push_back(vec3(x,y,z) * radius);
            if(r < rings-1)
                push_indices(indices, sectors, r, s);
        }
    }
}
3
ответ дан 28 November 2019 в 04:03
поделиться

Не похоже, чтобы кто-то до сих пор обращался к реальной проблеме с вашим исходным кодом, поэтому я подумал, что сделаю это, даже если вопрос уже довольно старый.

Проблема изначально была связана с проекцией относительно радиуса и положения сферы. Я думаю, вы обнаружите, что проблема не слишком сложна. Программа на самом деле работает правильно, просто то, что рисуется, очень трудно увидеть.

Сначала была создана ортогональная проекция с использованием вызова

gluOrtho2D(0.0, 499.0, 0.0, 499.0);

, который « эквивалентен вызову glOrtho с ближним = -1 и дальним = 1. » Это означает, что область просмотра имеет глубину 2. Таким образом, сфера с радиусом, превышающим 1 (диаметр = 2), не будет полностью вписываться в область просмотра.

Затем используются вызовы

glLoadIdentity();
glutSolidSphere(5.0, 20.0, 20.0);

, которые загружают единичную матрицу матрицы вида модели, а затем « [r] вводит сферу, центрированную в начале координат моделирования указанной radius. «То есть сфера отображается в начале координат (x, y, z) = (0, 0, 0) и имеет радиус 5.

Теперь проблема состоит из трех частей:

  1. Поскольку окно имеет размер 500x500 пикселей, а ширина и высота поля обзора составляет почти 500 (499,0), малый радиус сферы ( 5.0) делает проецируемую площадь лишь немного больше одной пятидесятой (2 * 5/499) от размера окна в каждом измерении. Это означает, что видимый размер сферы будет примерно 1/2500-й (фактически pi*5^2/499^2, что ближе к 1/3170-й) всего окна, поэтому может быть трудно увидеть . Это при условии, что весь круг нарисован в пределах области окна. Однако это не так, как мы увидим в пункте 2.
  2. Поскольку область обзора имеет левую плоскость в точке x = 0 и нижнюю плоскость в точке y = 0, сфера будет визуализироваться с геометрическим центром в самом нижнем левом углу окна, так что только один квадрант проецируемой сферы будет видно! Это означает, что то, что будет видно, будет еще меньше, примерно 1/10 000-й (на самом деле pi*5^2/(4*499^2), что ближе к 1/12 682-й) размера окна. Это сделало бы его еще труднее увидеть . Тем более, что сфера отображается настолько близко к краям / углу экрана, что вы можете и не подумать.
  3. Поскольку глубина поля зрения значительно меньше диаметра сферы (меньше половины), в области поля зрения будет только полоса сферы, отображающая только эту часть. Таким образом, вы получите больше похожий на полый круг на экране, чем на сплошную сферу / круг. Когда это происходит, толщина этого осколка может составлять менее 1 пикселя на экране, что означает, что мы можем даже не видеть ничего на экране, даже если часть сферы действительно находится в пределах усеченной области просмотра.

Решение состоит в том, чтобы просто изменить усеченный обзор и радиус сферы. Например,

gluOrtho2D(-5.0, 5.0, -5.0, 5.0);
glutSolidSphere(5.0, 20, 20);

рендерит следующее изображение.

r = 5.0

Как видите, вокруг экватора видна лишь небольшая часть сферы с радиусом 5. (Я изменил проекцию, чтобы заполнить окно со сферой.) Другой пример,

gluOrtho2D(-1.1, 1.1, -1.1, 1.1);
glutSolidSphere(1.1, 20, 20);

отображает следующее изображение.

r = 1.1

Изображение выше показывает большую часть сферы внутри усеченной области просмотра, но все же сфера на 0,2 единицы глубины больше, чем усеченная область просмотра. Как видите, «ледяные шапки» сферы отсутствуют как на севере, так и на юге. Итак, если мы хотим, чтобы вся сфера вписывалась в усеченный зрачок глубиной 2, мы должны сделать радиус меньше или равным 1.

gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutSolidSphere(1.0, 20, 20);

отображает следующее изображение.

r = 1.0

Надеюсь, это кому-то помогло. Береги себя!

21
ответ дан 28 November 2019 в 04:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: