คุณจะสร้างทรงกลมโดยทางโปรแกรมได้อย่างไร


25

ใครช่วยอธิบายได้ว่ามันจะเป็นไปได้อย่างไรในการสร้างจุดยอด, ดัชนีและพิกัดพื้นผิว มีการขาดเอกสารที่น่าแปลกใจเกี่ยวกับวิธีการทำเช่นนั้นและเป็นสิ่งที่ฉันสนใจในการเรียนรู้

ฉันได้ลองทำอย่างชัดเจน googling ดูบน gamedev.net ฯลฯ อย่างไรก็ตามไม่มีสิ่งใดครอบคลุมถึงจุดที่เป็นทรงกลมสร้างดัชนีเหล่านี้และพื้นผิว


6
ฉันจะไม่ลงคะแนนหรือลงคะแนนเพื่อปิดสิ่งนี้ แต่คุณจะบอกฉันหรือไม่ว่าไม่ใช่ผลลัพธ์เดียวจากgoogle.com/search?q=how+to+generate+a+sphere+verticesมีประโยชน์หรือไม่ หากเป็นกรณีนี้คุณจะต้องอธิบายว่าปัญหาของคุณคืออะไรโดยละเอียด


ค้นหา icosphere ฉลาดกว่า "ขั้วโลกทรงกลม" ที่เป็นใบ้ซึ่งสร้างใบหน้าที่ไร้ประโยชน์
Notabene

3
น่าสังเกตสำหรับจุดประสงค์ง่ายๆบางอย่าง "ทรงกลม" ที่ดีเลิศคือรูปสี่เหลี่ยมที่มีพื้นผิวเป็นวงกลมหันเข้าหากล้อง
aaaaaaaaaaaa

นี่คือวิธีที่ฉันใช้มันสำหรับ skydome ในเกมของฉัน
danijar

คำตอบ:


36

มีวิธีการทั่วไปสองวิธี:

ป้อนคำอธิบายรูปภาพที่นี่

ทางซ้ายสุดเรียกว่า uv-sphere และ icosphere ที่อยู่ทางขวาสุด

จำนวนที่มากเกินไปมีแนวโน้มที่จะใช้วิธีการ uv: ดูที่ฟังก์ชั่นglutSolidSphere()ในsourcecode freeglut

นี่คือบทความที่ยอดเยี่ยมเกี่ยวกับการผลิต icosphere: 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} ในกรณีของทรงกลม) เพื่อวัตถุประสงค์ในการทำแผนที่ UV
Martin Sojka

ทรงกลม icosahedral tessellated อย่างประณีตมีราคาแพงกว่าเล็กน้อยในการสร้างเพราะความต้องการที่จะแบ่งใบหน้าซ้ำ ๆ
bobobobo

9

มี 2 ​​วิธีในการทำ:

  1. เดิน theta และ phi ในพิกัดทรงกลมสร้างใบหน้าและ tris

  2. สร้าง icosahedron และแบ่งใบหน้าแบบวนซ้ำจนกว่าจะถึงเทสเซลเลชันที่ต้องการ

ทรงกลมโดยใช้พิกัดทรงกลมเดิน

สำหรับวิธีแรกคุณเพียงแค่ใช้ซ้อนกันสองครั้งเพื่อเดินทีต้าและพี เมื่อคุณเดิน theta และ phi คุณจะหมุนสามเหลี่ยมเพื่อสร้างทรงกลมของคุณ

ป้อนคำอธิบายรูปภาพที่นี่

รหัสที่ใช้จะมีลักษณะดังนี้:

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

ดังนั้นโปรดทราบด้านบนสิ่งสำคัญคือการหมุนฝาปิดด้านบนและฝาล่างโดยใช้เฉพาะทริสเท่านั้น

ทรงกลมแบบ Icosahedral

ในการใช้ icosahedron คุณเพียงแค่สร้างจุดของ icosahedron แล้วไขรูปสามเหลี่ยมออกจากมัน จุดของฮอว์คิงนั่งอยู่ที่ต้นกำเนิดคือ:

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

จากนั้นคุณต้องดูไดอะแกรมของ icosahedron และหน้าลมจาก verts เหล่านั้น ฉันมีรหัสที่ทำที่นี่แล้ว


ความคิดใดที่จะได้รับครึ่งร่างกายเช่นจาก theta = pi / 4 ถึง theta = 3pi * 4 ชอบรูปนี้: i.stack.imgur.com/Jjx2c.jpg ฉันใช้เวลาหลายวันกับสิ่งนี้ไม่สามารถแก้ไขได้
Tina J

3

หากจุดไม่จำเป็นต้องเหมือนกันทั้งในประเทศ แต่ควรจะเหมือนกันทั่วโลกและจะได้ไม่ต้องตามรูปแบบการตั้งค่าใด ๆ ที่คุณสามารถใช้ตัวแปรของอัลกอริทึมโผขว้างปาเพื่อแจกจ่ายnจุดบนทรงกลมที่มีรัศมีR , โดยเฉลี่ยจุดออกจากกัน ค่าเหล่านี้จะคร่าว ๆ :

  1. หากคุณต้องการมีจำนวนจุดยอด:
    • n = (จำนวนยอดที่ต้องการ)
    • dist = 2 × r ×√ ( π / n )
  2. หากคุณต้องการมีระยะทางเฉลี่ยเฉพาะระหว่างจุดยอด:
    • n = 4 × π × ( r / dist ) 2
    • dist = (ระยะทางเฉลี่ยที่ต้องการ)

ในกรณีที่ง่ายที่สุดคุณสามารถเลือกจุดสุ่มโดยการเลือกตัวแปรที่กระจายอย่างสม่ำเสมอสองตัวคือuและvจาก (0, 1) และคำนวณพิกัดเชิงขั้วจากพวกเขาตามสูตรθ = 2 × π × uและϕ = ส่วนโค้ง cos (2 × v - 1); จากนั้นให้ปิดจุดใด ๆ ที่อยู่ใกล้กับจุดที่เลือกไว้มากเกินไป สำหรับอัลกอริทึมที่ซับซ้อนและมีประสิทธิภาพที่ดีขึ้นเล็กน้อยดู " Dart Throwing on Surfaces " โดย Cline, Jeschke, White, Razdan และ Wonka

หลังจากที่คุณเลือกสี่คะแนนแรกของคุณ (สมมติว่าไม่มีสามคนที่แย่ลงนั่นคือ - พวกเขาไม่ได้อยู่ในวงกลมใหญ่เดียวกัน แต่ไม่น่าจะสูงมาก) คุณสามารถสร้างใบหน้าสี่ใบหน้าระหว่างพวกเขาและทุกครั้งที่คุณเพิ่ม จุดใหม่คุณสามารถแบ่งใบหน้าที่เป็นของมันออกเป็นสามใบหน้าย่อย

สำหรับจุดประสงค์การทำพื้นผิวจากนั้นคุณสามารถแมปจุดไปยังแผนที่คิวบ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.