2016-07-01 41 views
0

球の半分を作成しようとしています。基本的に球を作成するには、スタック番号とスライス番号が与えられます。phi(スライスの場合)とtheta(スタックの場合)の2つの変数があります。そしてプロセスは、ボトムキャップ、ボデー、トップキャップ(下記参照)の作成に分かれています。中半分(thetaは中程度の50%以下)を達成するには、キャップを省略して何らかの形で身体を修正する必要があります。私はスタック番号(1/4*stackNumbers to 3/4*stackNumbers)で遊んでいたが、私が望む結果を与えなかった。球の真ん中半分を描く方法(コード内)

真ん中半分(pi/4 <theta <pi*3/4)を達成するために球体生成をどのように変更すればよいですか?私の全体的な問題は、どのように球を3つの異なる部分、すなわち上25%、中50%、下25%に分けることができるかです。ここで、(角度換算で25%、すなわちtheta

は、プログラム球を生成するための人気のあるコードされる:

enter image description here

private void generateSphere(int stackNumber, int sliceNumber, boolean facingOut) { 
    int capVertexNumber = 3 * sliceNumber; 
    int bodyVertexNumber = 4 * sliceNumber * (stackNumber - 2); 
    int vertexNumber = (2 * capVertexNumber) + bodyVertexNumber; 
    int triangleNumber = (2 * capVertexNumber) + (6 * sliceNumber * (stackNumber - 2)); 

    vertices = new float[3 * vertexNumber]; 
    normals = new float[3 * vertexNumber]; 
    texCoords = new float[2 * vertexNumber]; 
    indices = new char[triangleNumber]; 

    // bottom cap 
    // createCap(stackNumber, sliceNumber, false, facingOut); 

    // body 
    createBody(stackNumber, sliceNumber, facingOut); 

    // top cap 
    createCap(stackNumber, sliceNumber, true, facingOut); 
} 

private void createCap(int stackNumber, int sliceNumber, boolean top, boolean facingOut) { 

    float stackPercentage0; 
    float stackPercentage1; 

    if (!top) { 
     stackPercentage0 = ((float) (stackNumber - 1)/stackNumber); 
     stackPercentage1 = 1.0f; 

    } else { 
     stackPercentage0 = (1.0f/stackNumber); 
     stackPercentage1 = 0.0f; 
    } 

    float t0 = stackPercentage0; 
    float t1 = stackPercentage1; 
    double theta0 = stackPercentage0 * Math.PI; 
    double theta1 = stackPercentage1 * Math.PI; 
    double cosTheta0 = Math.cos(theta0); 
    double sinTheta0 = Math.sin(theta0); 
    double cosTheta1 = Math.cos(theta1); 
    double sinTheta1 = Math.sin(theta1); 

    for (int slice = 0; slice < sliceNumber; slice++) { 
     float slicePercentage0 = ((float) (slice)/sliceNumber); 
     float slicePercentage1 = ((float) (slice + 1)/sliceNumber); 
     double phi0 = slicePercentage0 * 2.0 * Math.PI; 
     double phi1 = slicePercentage1 * 2.0 * Math.PI; 
     float s0, s1; 
     if (facingOut) { 
      s0 = 1 - slicePercentage0; 
      s1 = 1 - slicePercentage1; 
     } else { 
      s0 = slicePercentage0; 
      s1 = slicePercentage1; 
     } 
     float s2 = (s0 + s1)/2.0f; 
     double cosPhi0 = Math.cos(phi0); 
     double sinPhi0 = Math.sin(phi0); 
     double cosPhi1 = Math.cos(phi1); 
     double sinPhi1 = Math.sin(phi1); 

     float x0 = (float) (sinTheta0 * cosPhi0); 
     float y0 = (float) cosTheta0; 
     float z0 = (float) (sinTheta0 * sinPhi0); 

     float x1 = (float) (sinTheta0 * cosPhi1); 
     float y1 = (float) cosTheta0; 
     float z1 = (float) (sinTheta0 * sinPhi1); 

     float x2 = (float) (sinTheta1 * cosPhi0); 
     float y2 = (float) cosTheta1; 
     float z2 = (float) (sinTheta1 * sinPhi0); 

     vertices[vertexCount + 0] = x0; 
     vertices[vertexCount + 1] = y0; 
     vertices[vertexCount + 2] = z0; 

     vertices[vertexCount + 3] = x1; 
     vertices[vertexCount + 4] = y1; 
     vertices[vertexCount + 5] = z1; 

     vertices[vertexCount + 6] = x2; 
     vertices[vertexCount + 7] = y2; 
     vertices[vertexCount + 8] = z2; 

     if (facingOut) { 
      normals[vertexCount + 0] = x0; 
      normals[vertexCount + 1] = y0; 
      normals[vertexCount + 2] = z0; 

      normals[vertexCount + 3] = x1; 
      normals[vertexCount + 4] = y1; 
      normals[vertexCount + 5] = z1; 

      normals[vertexCount + 6] = x2; 
      normals[vertexCount + 7] = y2; 
      normals[vertexCount + 8] = z2; 
     } else { 
      normals[vertexCount + 0] = -x0; 
      normals[vertexCount + 1] = -y0; 
      normals[vertexCount + 2] = -z0; 

      normals[vertexCount + 3] = -x1; 
      normals[vertexCount + 4] = -y1; 
      normals[vertexCount + 5] = -z1; 

      normals[vertexCount + 6] = -x2; 
      normals[vertexCount + 7] = -y2; 
      normals[vertexCount + 8] = -z2; 
     } 

     texCoords[texCoordCount + 0] = s0; 
     texCoords[texCoordCount + 1] = t0; 
     texCoords[texCoordCount + 2] = s1; 
     texCoords[texCoordCount + 3] = t0; 
     texCoords[texCoordCount + 4] = s2; 
     texCoords[texCoordCount + 5] = t1; 

     if ((facingOut && top) || (!facingOut && !top)) { 
      indices[indexCount + 0] = (char) (triangleCount + 1); 
      indices[indexCount + 1] = (char) (triangleCount + 0); 
      indices[indexCount + 2] = (char) (triangleCount + 2); 
     } else { 
      indices[indexCount + 0] = (char) (triangleCount + 0); 
      indices[indexCount + 1] = (char) (triangleCount + 1); 
      indices[indexCount + 2] = (char) (triangleCount + 2); 
     } 

     vertexCount += 9; 
     texCoordCount += 6; 
     indexCount += 3; 
     triangleCount += 3; 
    } 

} 

private void createBody(int stackNumber, int sliceNumber, boolean facingOut) { 
    for (int stack = 1; stack < stackNumber - 1; stack++) { 
     float stackPercentage0 = ((float) (stack)/stackNumber); 
     float stackPercentage1 = ((float) (stack + 1)/stackNumber); 

     float t0 = stackPercentage0; 
     float t1 = stackPercentage1; 

     double theta0 = stackPercentage0 * Math.PI; 
     double theta1 = stackPercentage1 * Math.PI; 
     double cosTheta0 = Math.cos(theta0); 
     double sinTheta0 = Math.sin(theta0); 
     double cosTheta1 = Math.cos(theta1); 
     double sinTheta1 = Math.sin(theta1); 

     for (int slice = 0; slice < sliceNumber; slice++) { 
      float slicePercentage0 = ((float) (slice)/sliceNumber); 
      float slicePercentage1 = ((float) (slice + 1)/sliceNumber); 
      double phi0 = slicePercentage0 * 2.0 * Math.PI; 
      double phi1 = slicePercentage1 * 2.0 * Math.PI; 
      float s0, s1; 
      if (facingOut) { 
       s0 = 1.0f - slicePercentage0; 
       s1 = 1.0f - slicePercentage1; 
      } else { 
       s0 = slicePercentage0; 
       s1 = slicePercentage1; 
      } 
      double cosPhi0 = Math.cos(phi0); 
      double sinPhi0 = Math.sin(phi0); 
      double cosPhi1 = Math.cos(phi1); 
      double sinPhi1 = Math.sin(phi1); 

      float x0 = (float) (sinTheta0 * cosPhi0); 
      float y0 = (float) cosTheta0; 
      float z0 = (float) (sinTheta0 * sinPhi0); 

      float x1 = (float) (sinTheta0 * cosPhi1); 
      float y1 = (float) cosTheta0; 
      float z1 = (float) (sinTheta0 * sinPhi1); 

      float x2 = (float) (sinTheta1 * cosPhi0); 
      float y2 = (float) cosTheta1; 
      float z2 = (float) (sinTheta1 * sinPhi0); 

      float x3 = (float) (sinTheta1 * cosPhi1); 
      float y3 = (float) cosTheta1; 
      float z3 = (float) (sinTheta1 * sinPhi1); 

      vertices[vertexCount + 0] = x0; 
      vertices[vertexCount + 1] = y0; 
      vertices[vertexCount + 2] = z0; 

      vertices[vertexCount + 3] = x1; 
      vertices[vertexCount + 4] = y1; 
      vertices[vertexCount + 5] = z1; 

      vertices[vertexCount + 6] = x2; 
      vertices[vertexCount + 7] = y2; 
      vertices[vertexCount + 8] = z2; 

      vertices[vertexCount + 9] = x3; 
      vertices[vertexCount + 10] = y3; 
      vertices[vertexCount + 11] = z3; 

      if (facingOut) { 
       normals[vertexCount + 0] = x0; 
       normals[vertexCount + 1] = y0; 
       normals[vertexCount + 2] = z0; 

       normals[vertexCount + 3] = x1; 
       normals[vertexCount + 4] = y1; 
       normals[vertexCount + 5] = z1; 

       normals[vertexCount + 6] = x2; 
       normals[vertexCount + 7] = y2; 
       normals[vertexCount + 8] = z2; 

       normals[vertexCount + 9] = x3; 
       normals[vertexCount + 10] = y3; 
       normals[vertexCount + 11] = z3; 
      } else { 
       normals[vertexCount + 0] = -x0; 
       normals[vertexCount + 1] = -y0; 
       normals[vertexCount + 2] = -z0; 

       normals[vertexCount + 3] = -x1; 
       normals[vertexCount + 4] = -y1; 
       normals[vertexCount + 5] = -z1; 

       normals[vertexCount + 6] = -x2; 
       normals[vertexCount + 7] = -y2; 
       normals[vertexCount + 8] = -z2; 

       normals[vertexCount + 9] = -x3; 
       normals[vertexCount + 10] = -y3; 
       normals[vertexCount + 11] = -z3; 
      } 

      texCoords[texCoordCount + 0] = s0; 
      texCoords[texCoordCount + 1] = t0; 
      texCoords[texCoordCount + 2] = s1; 
      texCoords[texCoordCount + 3] = t0; 
      texCoords[texCoordCount + 4] = s0; 
      texCoords[texCoordCount + 5] = t1; 
      texCoords[texCoordCount + 6] = s1; 
      texCoords[texCoordCount + 7] = t1; 

      // one quad looking from outside toward center 
      // 
      // @formatter:off 
      // 
      // s1 --> s0 
      // 
      // t0 1-----0 
      // | | | 
      // v | | 
      // t1 3-----2 
      // 
      // @formatter:on 
      // 
      // Note that tex_coord t increase from top to bottom because the 
      // texture image is loaded upside down. 
      if (facingOut) { 
       indices[indexCount + 0] = (char) (triangleCount + 0); 
       indices[indexCount + 1] = (char) (triangleCount + 1); 
       indices[indexCount + 2] = (char) (triangleCount + 2); 

       indices[indexCount + 3] = (char) (triangleCount + 2); 
       indices[indexCount + 4] = (char) (triangleCount + 1); 
       indices[indexCount + 5] = (char) (triangleCount + 3); 
      } else { 
       indices[indexCount + 0] = (char) (triangleCount + 0); 
       indices[indexCount + 1] = (char) (triangleCount + 2); 
       indices[indexCount + 2] = (char) (triangleCount + 1); 

       indices[indexCount + 3] = (char) (triangleCount + 2); 
       indices[indexCount + 4] = (char) (triangleCount + 3); 
       indices[indexCount + 5] = (char) (triangleCount + 1); 
      } 

      vertexCount += 12; 
      texCoordCount += 8; 
      indexCount += 6; 
      triangleCount += 4; 
     } 
    } 

} 
+0

どのようにして25%を定義しますか?シリンダーの容積による?角度によって? –

+0

createArcを見てください。それはあなたがしたいこととは逆のことです。しかし、実際には逆の場合は、球からArea.subtractを使用して、必要なものを得ることができます。 https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/ui/util/ShapeUtils.java – ControlAltDel

+0

@NicolBolas角度( 'Theta') –

答えて

1

コードここでは、球体を計算するspherical coordinatesを使用しています。 thetaは、あなたが興味のある上/下座標を表す変数で、thetaは0からPIになります。あなたはPI/4から3PI/4へ行きたいです。 stackNumbersは球の分割数を表しています。スタックの分母として使用されていることが分かります。これは変更する変数が間違っています。したがって、代わりにコードに以下の変更を加えることができます。投稿者:

double theta0 = stackPercentage0 * Math.PI; 
double theta1 = stackPercentage1 * Math.PI; 

へ:

double startTheta = Math.PI/4; 
double endTheta = 3 * Math.PI/4; 
double theta0 = stackPercentage0 * (endTheta - startTheta) + startTheta; 
double theta1 = stackPercentage1 * (endTheta - startTheta) + startTheta; 

そして、あなたは、あなたがそれを反映するために、開始と終了のスタック番号を変更する必要はキャップを使用していないので、:また

for (int stack = 1; stack < stackNumber - 1; stack++) { // old 
for (int stack = 0; stack < stackNumber; stack++) { // new 

を、あなたは今より多くの体の顔を持っているので、あなたはそれらのために適切なコンテナを更新する必要があります。 (stackNumber - 2)(stackNumber - 1)に置き換えてください。

+0

最初の修正( 'theta'の場合)が有効であるようです。しかし、あなたは身体が帽子から分離していることをコードで気付いたのですか?あなたは 'for(int stack = 0')部分(私のイメージの上部はもう切断されません)で正しいですが、' stack

+0

はい、私はそれらが別々であることを知っていますランタイムエラーは何ですか? – meepzh

+0

Ok、 - 1'は現在動作していますが、画像の下端部分(おそらく最後のスタック)は、元の画像を出力と比較してカットされます。 –

関連する問題