Programlı olarak nasıl küre yaratırsınız?


25

Birisi bir küre köşeleri, indeksleri ve doku koordinatları oluşturmanın nasıl mümkün olacağını açıklayabilir mi? Bunun nasıl yapılacağına dair şaşırtıcı bir dokümantasyon eksikliği var ve bu benim öğrenmek istediğim bir şey.

Bariz, googling, gamedev.net, vb. Bakmayı denedim. Ancak hiçbir şey küresel noktaların neslini, endekslemesini ve tekstüre dahil değildir.


6
Bunu kapatmak için oy kullanmaya ya da oy kullanmayacağım, ama bana gerçekten google.com/search?q=how+to+generate+a+sphere+vertices adresinden tek bir sonuç gelmediğini mi söylüyorsunuz ? Durum buysa, probleminizin ne olduğunu daha ayrıntılı olarak açıklamanız gerekir.


Icosphere arayın. İşe yaramaz yüzler üreten aptal "kutupsal küre" den çok daha akıllı.
Notabene

3
Dikkat çekmeye değer, bazı basit amaçlar için mükemmel bir ince "küre", kameraya bakan dairesel bir yapıya sahip bir dörtlüdür.
aaaaaaaaaaaa

İşte oyunumda skydome için nasıl uyguladım .
danijar

Yanıtlar:


36

İki genel yaklaşım vardır:

görüntü tanımını buraya girin

En solda, uv küresi ve en sağda bir ikosfer denir.

Fonksiyonuna bakmak: GLUT uv yaklaşım kullanmak eğiliminde glutSolidSphere()içinde freeglut sourcecode .

Bir icosphere üretme konusunda harika bir makale: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

UV-küre bir küre gibi görünüyor. Birçok amaç için tamamen iyidir, ancak bazı kullanım durumlarında, örneğin küreyi deforme etmek istiyorsanız, köşelerin yoğunluğunun kutupların çevresinde daha büyük olması dezavantajlıdır. Burada icosphere iyidir, köşeleri eşit olarak dağılmıştır.

Bunu da ilginç bulabilirsiniz: http://kiwi.atmos.colostate.edu/BUGS/geodesic/text.html , yüzleri bölgelere ayırma yaklaşımını açıklar.

http://vterrain.org/Textures/spherical.html , onları nasıl dokulandırmayı seçebileceğiniz konusunda mükemmel bir açıklama sunar.


2
Genel fikir iyi olsa da, bir Schläfli {3,5} polytopunu bölmek bunu yapmanın tek yolu değildir. Genel olarak, UV haritalama amaçları için Schläfli {4, *} ailesiyle (bir küre durumunda {4,3}) çalışmayı tercih ederim.
Martin Sojka,

İnce mozaikli ikosahedral küreler, yüzleri özyinelemeli olarak alt bölümlere ayırma ihtiyacı nedeniyle, üretilmesi biraz daha pahalıdır.
bobobobo

9

Bunu yapmanın 2 yolu vardır:

  1. Theta ve phi'yi küresel koordinatlarda yürü, yüz ve tris oluştur

  2. Bir icosahedron oluşturun ve istenen mozaikleme elde edilene kadar özyinelemeli yüzler bölün.

Küresel koordinatları kullanarak küre yürümek

İlk olarak, teta ve phi'yi yürümek için sadece bir yuvalanmış çift kullanın. Teta ve phi'yi yürürken, kürenizi oluşturmak için üçgenleri döndürürsünüz.

görüntü tanımını buraya girin

Bunu yapan kod şöyle görünecek:

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

Bu yüzden yukarıda not edin, üst kapağı ve alt kapağı dörtlü değil sadece tris kullanarak sarmak önemlidir.

Icosahedral küre

Bir icosahedron kullanmak için, sadece icosahedron'un noktalarını yaratır ve ondan üçgenler çıkarırsınız. Bir icosahedron köşe kökenli oturan şunlardır:

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

O zaman sadece bir ikosahedron şemasına bakmalısınız ve bu rüzgarlardaki rüzgar yüzleri. Zaten burada bunu yapan kodum var .


theta = pi / 4'ten theta = 3pi * 4'e kadar olan yarım cesedi nasıl elde edebileceğinize dair bir fikriniz var mı? Bu resimdeki gibi: i.stack.imgur.com/Jjx2c.jpg Bunun üzerinde günler harcadım.
Tina J

3

Noktaları lokal olarak homojen olması gerekmez, ancak küresel olarak tek tip olmalı ve herhangi bir oturma modelini takip etmek zorunda yoksa, sen dağıtmak için dart atma algoritması bir varyantını kullanabilirsiniz n yarıçapı olan bir kürenin üzerindeki noktaları r , ortalama dağılma noktası ayrı. Bu değerler daha sonra kabaca:

  1. Belirli bir miktar köşeye sahip olmak istiyorsanız:
    • n = (istenilen miktarda köşe)
    • dist = 2 × r × √ ( π / n )
  2. Köşeler arasında belirli bir ortalama mesafe olmasını istiyorsanız:
    • n = 4 x π x ( r / dist ) 2
    • dist = (istenen ortalama uzaklık)

En basit durumda, daha sonra muntazam şekilde iki eşit dağılmış değişkenleri seçerek rastgele sayı almak için u ve v formüllere göre (0, 1) den ve onları polar koordinatlarının θ = 2 x π x u ve φ = ark cos (2 x v - 1); daha sonra, önceden seçilmiş olan noktalara çok yakın olan noktaları reddetmek. Biraz daha karmaşık ve önemli ölçüde daha iyi performans gösteren algoritma için bkz " Yüzeylerde dart atan Cline, JESCHKE, Beyaz, Razdan ve Wonka tarafından".

İlk dört noktanızı seçtikten sonra (üçünün dejenere olmadığını varsayalım , yani - aynı büyük çevrede yatmazlar, ancak bu pek olası değildir), aralarında dört yüz oluşturabilirsiniz ve yeni nokta, ait olduğu yüzü buna göre üç alt yüze bölebilirsiniz.

Tekstüre etme amacıyla, noktaları bir küp haritasına eşleyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.