Bagaimana Anda secara terprogram menghasilkan bola?

25

Bisakah seseorang tolong jelaskan bagaimana mungkin untuk membuat simpul bola, indeks dan koordinat tekstur? Ada kekurangan dokumentasi yang mengejutkan tentang bagaimana melakukannya dan itu adalah sesuatu yang saya tertarik untuk pelajari.

Saya sudah mencoba yang jelas, googling, mencari di gamedev.net, dll. Namun, tidak ada yang mencakup generasi titik bola, pengindeksan, dan texturing.

judeclarke
sumber
6
Saya tidak akan menurunkan suara atau memilih untuk menutup ini, tetapi apakah Anda benar-benar memberi tahu saya bahwa tidak ada satu pun hasil dari google.com/search?q=how+to+generate+a+sphere+vertices berguna? Jika itu masalahnya, Anda harus menjelaskan masalah Anda secara lebih rinci.
Cari icosphere. Jauh lebih pintar daripada "bola kutub" bodoh yang menghasilkan wajah yang tidak berguna.
Notabene
3
Patut dicatat, untuk beberapa tujuan sederhana "bola" yang sangat bagus adalah quad dengan tekstur melingkar menghadap kamera.
aaaaaaaaaaaa
Inilah cara saya mengimplementasikannya untuk skydome di game saya.
danijar

Jawaban:

36

Ada dua pendekatan umum:

masukkan deskripsi gambar di sini

Yang paling kiri disebut uv-sphere dan yang paling kanan adalah icosphere.

GLUT cenderung menggunakan pendekatan uv: lihat fungsi glutSolidSphere()dalam kode sumber freeglut .

Berikut ini adalah artikel yang sangat baik tentang cara menghasilkan icosphere: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

Bola-uv terlihat seperti bola dunia. Untuk banyak tujuan itu baik-baik saja, tetapi untuk beberapa kasus penggunaan, misalnya jika Anda ingin merusak bola, itu tidak menguntungkan bahwa kepadatan simpul lebih besar di sekitar kutub. Di sini icosphere lebih baik, simpulnya didistribusikan secara merata.

Anda juga dapat menemukan ini menarik: http://kiwi.atmos.colostate.edu/BUGS/geodesic/text.html ini menggambarkan pendekatan untuk mengatur wajah ke dalam zona.

http://vterrain.org/Textures/spherical.html memberikan deskripsi yang sangat baik tentang bagaimana Anda dapat memilih untuk tekstur mereka.

Akan
sumber
2
Walaupun ide umumnya bagus, membagi polytope Schläfli {3,5} bukanlah satu-satunya cara untuk melakukannya. Secara umum, saya lebih suka bekerja dengan keluarga Schläfli {4, *} ({4,3} jika menggunakan lingkup) untuk keperluan pemetaan UV.
Martin Sojka
Bola icosahedral yang halus dan tessellated sedikit lebih mahal untuk dihasilkan karena kebutuhan untuk membagi wajah secara rekursif.
bobobobo
9

Ada 2 cara untuk melakukannya:

  1. Berjalanlah theta dan phi dalam koordinat bola, menghasilkan wajah dan tris

  2. Buat icosahedron dan membagi wajah secara rekursif sampai tessellation yang diinginkan tercapai.

Bola menggunakan koordinat bola berjalan

Untuk cara pertama, Anda hanya menggunakan sarang ganda untuk berjalan theta dan phi. Saat Anda berjalan theta dan phi, Anda memutar segitiga untuk membuat bola Anda.

masukkan deskripsi gambar di sini

Kode yang melakukannya akan terlihat seperti ini:

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 ) ;
    }
  }
}

Jadi perhatikan di atas, penting untuk memutar tutup atas dan tutup bawah hanya menggunakan tris, bukan paha depan.

Lingkungan Icosahedral

Untuk menggunakan icosahedron, Anda hanya menghasilkan titik-titik icosahedron dan kemudian menghasilkan segitiga dari itu. The simpul dari sebuah icosahedron duduk di asal adalah:

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

Anda kemudian harus melihat diagram icosahedron dan wajah angin dari verts tersebut. Saya sudah punya kode yang melakukannya di sini .

bobobobo
sumber
ada ide bagaimana mendapatkan setengah tubuh, seperti dari theta = pi / 4 ke theta = 3pi * 4? Seperti gambar ini: i.stack.imgur.com/Jjx2c.jpg Saya sudah menghabiskan waktu berhari-hari dalam hal ini tidak dapat menyelesaikannya.
Tina J
3

Jika titik tidak harus seragam secara lokal, tetapi harus seragam global, dan tidak harus mengikuti pola pengaturan apa pun, Anda dapat menggunakan varian algoritma pelemparan panah untuk mendistribusikan n titik pada bola dengan jari-jari r , rata-rata dist poin terpisah. Nilai-nilai ini kemudian kira-kira:

  1. Jika Anda ingin memiliki jumlah simpul tertentu:
    • n = (jumlah simpul yang diinginkan)
    • dist = 2 × r × √ ( π / n )
  2. Jika Anda ingin memiliki jarak rata-rata spesifik antara simpul:
    • n = 4 × π × ( r / dist ) 2
    • dist = (jarak rata-rata yang diinginkan)

Dalam kasus paling sederhana, Anda kemudian dapat secara seragam memilih titik secara acak dengan memilih dua variabel terdistribusi seragam u dan v dari (0, 1) dan menghitung koordinat kutub dari mereka sesuai dengan rumus θ = 2 × π × u dan ϕ = arc cos (2 × v - 1); kemudian mengabaikan poin yang terletak terlalu dekat dengan poin yang sudah dipilih. Untuk algoritma yang sedikit lebih kompleks dan berkinerja lebih baik, lihat " Dart Throwing on Surface" oleh Cline, Jeschke, White, Razdan dan Wonka.

Setelah Anda mengambil empat poin pertama Anda (dengan asumsi tidak ada tiga dari mereka yang merosot , yaitu - mereka tidak terletak pada lingkaran besar yang sama, tapi itu sangat tidak mungkin), Anda dapat membuat empat wajah di antara mereka, dan setiap kali Anda menambahkan titik baru, Anda dapat membagi wajah itu miliknya menjadi tiga sub-wajah.

Untuk keperluan texturing, Anda dapat memetakan titik ke peta kubus.

Martin Sojka
sumber