プログラムで球をどのように生成しますか?


25

誰かが球の頂点、インデックス、テクスチャ座標を作成する方法を説明してもらえますか?これを行う方法についてのドキュメントが驚くほど不足しており、私は学習に興味を持っています。

gamedev.netなどで明らかな、グーグル、ルックなどを試してみました。しかし、球体ポイントの生成、それらのインデックス付け、テクスチャリングはカバーしていません。


6
私はこれを閉じるためにdownvoteまたは投票つもりはありませんが、あなたは本当にから単一の結果ではないことを私に言っているgoogle.com/search?q=how+to+generate+a+sphere+verticesが便利でしたか?その場合は、問題の詳細を説明する必要があります。


icosphereを検索します。役に立たない顔を生成する愚かな「極圏」よりもはるかに賢い。
ノタベン

3
注目に値するのは、いくつかの単純な目的のために、完全に細かい「球体」は、カメラに面した円形のテクスチャを持つ四角形です。
aaaaaaaaaaaa

ゲーム内のスカイドームにどのように実装したかを以下に示します
ダニジャー

回答:


36

2つの一般的なアプローチがあります。

ここに画像の説明を入力してください

左端はuv球体、右端はicosphereと呼ばれます。

GLUTはuvアプローチを使用する傾向があります:freeglutソースコードの関数glutSolidSphere()を見てください

ここでicosphereを生産する上で優れた記事は以下のとおりです。http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html

紫外線球は球体のように見えます。多くの目的では完全に問題ありませんが、たとえば球体を変形したい場合など、ユースケースによっては、極の周りの頂点の密度が大きいという欠点があります。ここでは、icosphereの方が優れており、頂点は均等に分布しています。

また、これは興味深いかもしれません:http : //kiwi.atmos.colostate.edu/BUGS/geodesic/text.htmlそれは、顔をゾーンに整理するアプローチを説明しています。

http://vterrain.org/Textures/spherical.htmlは、テクスチャを選択する方法の優れた説明を提供します。


2
一般的な考え方は優れていますが、Schläfli{3,5}ポリトープを細分化することはそれを行う唯一の方法ではありません。一般的に、UVマッピングの目的でSchläfli{4、*}ファミリー(球体の場合は{4,3})で作業することを好みます。
マーティンソイカ

細かくテッセレーションされた二十面体球は、再帰的に面を再分割する必要があるため、生成するのに少し費用がかかります。
ボボボボ

9

それを行うには2つの方法があります。

  1. 球座標でシータとファイを歩いて、面とトリスを生成します

  2. 二十面体を作成し、目的のテッセレーションに達するまで再帰的に面を細分割します。

球面座標ウォークを使用した球

最初の方法では、ダブルネストされたforを使用して、シータとファイをウォークします。シータとファイを歩くと、三角形を回転させて球体を作成します。

ここに画像の説明を入力してください

それを行うコードは次のようになります。

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

そのため、上キャップと下キャップをクワッドではなくトライのみで巻き取ることが重要です。

二十面体球

二十面体を使用するには、二十面体のポイントを生成し、そこから三角形を巻き上げます。原点にある20面体頂点は次のとおりです。

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

次に、20面体とそれらの頂点からの風の面の図を見なければなりません。私はすでにここでそれを行うコードを持っています


theta = pi / 4からtheta = 3pi * 4など、半身を取得する方法はありますか?この画像のように:i.stack.imgur.com/Jjx2c.jpgこれに何日も費やしましたが、解決できませんでした。
ティナJ

3

ポイントがローカルに均一である必要はないが、グローバルに均一である必要があり、設定されたパターンに従う必要がない場合は、ダーツ投げアルゴリズムのバリアントを使用して、半径rの球にn個のポイントを分散できます。平均してdistポイントは離れています。これらの値は大体次のとおりです。

  1. 特定の量の頂点が必要な場合:
    • n =(頂点の望ましい量)
    • dist = 2× r ×√(π / n
  2. 頂点間の特定の平均距離が必要な場合:
    • n = 4× π ×(r / dist2
    • dist =(望ましい平均距離)

最も簡単なケースでは、(0、1)から2つの均一に分布した変数uおよびvを選択し、式θ = 2× π × uおよびϕ = arc に従って極座標を計算することにより、ランダムに均一にポイントを選択できますcos(2× v -1); 次に、既に選択されているポイントに近すぎるポイントをすべて削除します。やや複雑でパフォーマンスが大幅に向上したアルゴリズムについては、Cline、Jeschke、White、Razdan、およびWonkaによる「Dart Throwing on Surfaces」を参照してください。

最初の4つのポイントを選択した後(それらの3つが縮退していないと仮定すると、つまり、それらは同じ大円上にないが、それはほとんどありそうにない)、それらの間に4つの面を作成し、追加するたびに新しいポイントでは、それに属する面を3つのサブ面に分割できます。

テクスチャリングの目的で、ポイントをキューブマップにマップできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.