Як ви програмно генеруєте сферу?


25

Чи не могли б хтось пояснити, як можна було б створити вершини, індекси та координати текстури сфери? На диво бракує документації, як це зробити, і мені цікаво дізнатись.

Я спробував очевидне, гугле, дивлячись на gamedev.net і т. Д. Однак ніщо не охоплює покоління сферичних точок, їх індексацію та текстурування.


6
Я не збираюся голосувати чи голосувати за те, щоб закрити це, але чи справді ви мені говорите, що жоден результат із google.com/search?q=how+to+generate+a+sphere+vertices не був корисним? Якщо це так, вам потрібно пояснити, у чому полягає ваша проблема.


Шукайте ікосферу. Набагато розумніша за тупу "полярну сферу", яка створює марні обличчя.
Нотабене

3
Варто зауважити, що для деяких простих цілей ідеально тонкою «сферою» є квадратик з круглою текстурою, зверненою до камери.
aaaaaaaaaaaa

Ось як я реалізував це для skydome у своїй грі.
danijar

Відповіді:


36

Є два загальні підходи:

введіть тут опис зображення

Крайні ліві називаються uv-сферою, а права права ікосферою.

GLUT прагне використовувати підхід Uv: подивіться на функцію glutSolidSphere()у вихідному коді freeglut .

Ось чудова стаття про створення ікосфери: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

Ув-сфера схожа на земну кулю. Для багатьох цілей це прекрасно, але для деяких випадків використання, наприклад, якщо ви хочете деформувати сферу, невигідно, щоб щільність вершин була більша навколо полюсів. Тут ікосфера краще, її вершини розподілені рівномірно.

Також вам це може бути цікаво: http://kiwi.atmos.colostate.edu/BUGS/geodesic/text.html він описує підхід до організації обличчя в зони.

http://vterrain.org/Textures/spherical.html дає чудовий опис того, як ви можете обрати їх текстуру.


2
Хоча загальна ідея хороша, підрозділення політопа Schläfli {3,5} є не єдиним способом його здійснення. Як правило, я віддаю перевагу роботі з родиною Schläfli {4, *} ({4,3} у випадку сфери) для цілей УФ-карти.
Мартін Сойка

Дрібно тесельовані ікосаедричні сфери генерують трохи дорожче через необхідність рекурсивно розподіляти грані.
bobobobo

9

Є два способи зробити це:

  1. Гуляйте по теті та фі в сферичних координатах, створюйте обличчя та трис

  2. Створіть ікосаедр і рекурсивно розділіть обличчя, поки не буде досягнуто бажаної тесселяції.

Сфера за допомогою сферичних координат ходи

По-перше, ви просто використовуєте подвійне вкладене для ходіння по теті та фі. Коли ви ходите по теті та фі, ви обертаєте трикутники, щоб створити свою сферу.

введіть тут опис зображення

Код, який це робить, буде виглядати приблизно так:

for( int t = 0 ; t < stacks ; t++ ) // stacks are ELEVATION so they count theta
{
  real theta1 = ( (real)(t)/stacks )*PI ;
  real theta2 = ( (real)(t+1)/stacks )*PI ;

  for( int p = 0 ; p < slices ; p++ ) // slices are ORANGE SLICES so the count azimuth
  {
    real phi1 = ( (real)(p)/slices )*2*PI ; // azimuth goes around 0 .. 2*PI
    real phi2 = ( (real)(p+1)/slices )*2*PI ;

    //phi2   phi1
    // |      |
    // 2------1 -- theta1
    // |\ _   |
    // |    \ |
    // 3------4 -- theta2
    //

    //vertex1 = vertex on a sphere of radius r at spherical coords theta1, phi1
    //vertex2 = vertex on a sphere of radius r at spherical coords theta1, phi2
    //vertex3 = vertex on a sphere of radius r at spherical coords theta2, phi2
    //vertex4 = vertex on a sphere of radius r at spherical coords theta2, phi1

    // facing out
    if( t == 0 ) // top cap
      mesh->addTri( vertex1, vertex3, vertex4 ) ; //t1p1, t2p2, t2p1
    else if( t + 1 == stacks ) //end cap
      mesh->addTri( vertex3, vertex1, vertex2 ) ; //t2p2, t1p1, t1p2
    else
    {
      // body, facing OUT:
      mesh->addTri( vertex1, vertex2, vertex4 ) ;
      mesh->addTri( vertex2, vertex3, vertex4 ) ;
    }
  }
}

Отже, зверніть увагу на те, що важливо намотувати верхню та нижню шапки, використовуючи лише трис, а не квадратики.

Ікосаедральна сфера

Щоб використовувати ікосаедр, ви просто генеруєте точки ікосаедра, а потім намотуєте з нього трикутники. У вершинах ікосаедра сидить в нулі є:

(0, ±1, ±φ)
1, ±φ, 0)
(±φ, 0, ±1)
where φ = (1 + 5) / 2 

Тоді вам доведеться просто подивитися схему ікосаедра та граней вітру з цих вершин. У мене вже є код, який це робить тут .


будь-які ідеї, як отримати половину тіла, як від theta = pi / 4 до theta = 3pi * 4? Подобається це зображення: i.stack.imgur.com/Jjx2c.jpg Я витрачав цілі дні на це, не міг її вирішити.
Тіна J

3

Якщо точки не повинні бути локально рівномірними, але мають бути глобально однаковими, і не потрібно дотримуватися жодної заданої схеми, ви можете використовувати варіант алгоритму кидання дартс для розподілу n точок на сферу з радіусом r , в середньому DIST пунктів один від одного. Ці значення потім приблизно:

  1. Якщо ви хочете мати конкретну кількість вершин:
    • n = (бажана кількість вершин)
    • dist = 2 × r × √ ( π / n )
  2. Якщо ви хочете мати певну середню відстань між вершинами:
    • n = 4 × π × ( r / dist ) 2
    • dist = (бажана середня відстань)

У найпростішому випадку ви можете рівномірно вибрати точки навмання, вибравши дві рівномірно розподілені змінні u і v з (0, 1) та обчисливши від них полярні координати за формулами θ = 2 × π × u та ϕ = дуга cos (2 × v - 1); потім відкидає будь-які точки, які лежать занадто близько до вже вибраних балів. Про дещо складніший та значно ефективніший алгоритм дивіться у розділі " Стріляння з металів на поверхні " Клайна, Джешка, Білого, Раздана та Вонка.

Після того, як ви вибрали свої перші чотири точки (якщо припустити, що три з них не вироджуються , тобто - вони не лежать на одному великому колі, але це малоймовірно), ви можете створити між ними чотири обличчя, і кожен раз додаючи Новий момент, ви можете розділити обличчя, якому воно належить, відповідно на три субграні.

Для текстурування цілей ви можете зіставити точки на карту кубів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.