2009-08-25 21 views
3

私は次のコードでのJava 3Dで描いたコーンを持っている:Java 3Dでオブジェクトを回転するには?

Cone cone = new Cone(2f, 3f); 

Transform3D t3d = new Transform3D(); 
TransformGroup coneTransform = new TransformGroup(t3d); 
coneTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 

t3d.setTranslation(new Vector3f(0f,0f,0f); 
coneTransform.setTransform(t3d); 
coneTransform.addChild(cone); 

this.addChild(coneTransform); 

は、私はポイント(1,1,1)の前に座っコーンを持っていると仮定し、私は、円錐の先端が下に指すようにしたいです想像線は(0,0,0)と(1,1,1)を通っています...どうすればいいですか?すべての助けを事前に

Transform3D t3d = new Transform3D(); 

Vector3f direction = new Vector3f(1,2,1);  

final double angleX = direction.angle(new Vector3f(1,0,0)); 
final double angleY = direction.angle(new Vector3f(0,1,0)); 
final double angleZ = direction.angle(new Vector3f(0,0,1)); 

t3d.rotX(angleX); 
t3d.rotY(angleY); 
t3d.rotZ(angleZ); 

t3d.setTranslation(direction); 

coneTransform.setTransform(t3d); 

感謝を:ここで

は、私がしようとしてきたものの一例です!

答えて

1

ここで私が学んだクォータニオンを使って、何をしたいのかが分かりました:http://www.cs.uic.edu/~jbell/Courses/Eng591_F1999/outline_2.html私の解答です。

コーンの作成:今すぐ

private void attachCone(float size) { 
     Cone cone = new Cone(size, size* 2); 

     // The group for rotation 
     arrowheadRotationGroup = new TransformGroup(); 
     arrowheadRotationGroup. 
      setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 
     arrowheadRotationGroup.addChild(cone); 

     // The group for positioning the cone 
     arrowheadPositionGroup = new TransformGroup(); 
     arrowheadPositionGroup. 
       setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 
     arrowheadPositionGroup.addChild(arrowheadRotationGroup); 

     super.addChild(arrowheadPositionGroup); 
    } 

、私は(direction.xにポイント(0,0,0)からのベクトルとして指定された特定の方向を向いているために、コーンを回転させたいとき、 direction.y、direction.z)は、私が使用します。

private final Vector3f yAxis = new Vector3f(0f, 1f, 0f); 
private Vector3f direction; 

private void rotateCone() { 
     // Get the normalized axis perpendicular to the direction 
     Vector3f axis = new Vector3f(); 
     axis.cross(yAxis, direction); 
     axis.normalize(); 

     // When the intended direction is a point on the yAxis, rotate on x 
     if (Float.isNaN(axis.x) && Float.isNaN(axis.y) && Float.isNaN(axis.z)) 
     { 
      axis.x = 1f; 
      axis.y = 0f; 
      axis.z = 0f; 
     } 
     // Compute the quaternion transformations 
     final float angleX = yAxis.angle(direction); 
     final float a = axis.x * (float) Math.sin(angleX/2f); 
     final float b = axis.y * (float) Math.sin(angleX/2f); 
     final float c = axis.z * (float) Math.sin(angleX/2f); 
     final float d = (float) Math.cos(angleX/2f); 

     Transform3D t3d = new Transform3D(); 
     Quat4f quat = new Quat4f(a, b, c, d); 
     t3d.set(quat); 
     arrowheadRotationGroup.setTransform(t3d); 

     Transform3D translateToTarget = new Transform3D(); 
     translateToTarget.setTranslation(this.direction); 
     arrowheadPositionGroup.setTransform(translateToTarget); 
    } 
0

私は、これはそれを行うべきだと思う:

coneTransform.rotX(Math.PI/4); 
coneTransform.rotY(Math.PI/4); 
+0

ありがとうございます。 t3d.rotX(Math.PI/2);同様にYについては、Zは円錐を回転させる。 XとYを回転させる角度を計算する方法を記述できますか?たとえば、(0,0,0)から(1,1,1)に線を引いた場合、回転量を計算する方法は? – Cuga

+1

回転関数は、ラジアン値を入力として取ります。 2 * PIが完全に1回転する、または垂直線の間にPI/2度がある(これは私が間違っていて、PI/4のみを回転させる必要があることを意味する)。 一般に、3つの角度に沿って回転する必要はありません。 – Zed

+0

母 - 私はちょうど3回転のすべてを必要としないことに気づいた。私は今、私が必要とする角度をどのように計算するかを紙に書いています。ご協力いただきありがとうございます。 – Cuga

2

これは、Java3Dの具体的な答えではありません。

一般に、マトリックスは、それを記述する4つのベクトルがあるように構築することができます。

1)側(又は横方向)ベクトル
2)アップベクトル
3)方向ベクトル
4)の4×4行列の位置

各行。

したがって、単純な単位行列の場合、次の行列があります(行の主行列を定義します。行の主行列の場合は、行2のcol 3が行3マトリックス全体にわたって2列目)。

1 0 0 0 
0 1 0 0 
0 0 1 0 
0 0 0 1 

この最初の列はサイドベクトルです。 2番目の列はアップベクトルです。 3番目の方向と4番目の位置。

論理的には、ベクトル(1,0,0,0)がx軸に沿ってポイントする(したがってサイドベクトルである)ことがわかります。ベクトル(0,1,0,0)は、y軸に沿って指し示す(したがって、アップベクトルである)。 Z軸に沿った3番目の(0,0,1,0)点(したがって、方向ベクトル)です。 4番目の(0、0、0、1)は、オブジェクトがまったく動かないことを示します。

ここで、X軸に沿って向きたいとしましょう。

明らかに、それは私たちが方向ベクトルに対して(1,0,0,0)のベクトルを持つことを意味します。 Upはまだ(0,1,0,0)であり、位置はまだ0,0,0,1です。したがって、サイドベクトルはどのようになりますか?まあ、論理的にはz軸に沿って指しています。しかし、どのように?片方の指が前方を指し、一方が片側を向くように指を保持します。前方の指がサイド指の指と同じ方向を向くように回転させます。どの方向に指を指しているのか?元の方向指示指とは反対の方向。したがって、マトリックスは

0 0 1 0 
0 1 0 0 
-1 0 0 0 
0 0 0 1 

です。この時点では、一見少し複雑になります。任意の位置と任意の点を見るだけで簡単です(私はそれらをvPosとvFocusと呼ぶ)。 vFocus(vFocus.x - vPos.x、vFocus.y - vPos.y、vFocus.z - vPos.z、vFocus.w - vPos.w)からvPosを減算することによって、vPosからvFocusへのベクトルを形成するのは簡単です。すべてのポジションが '0'であるwポジションでは、すべてのポジションを '1'で定義する必要があります。これは、両方のwの1がキャンセルして0を残すので、上記の減算を行うと、自動的に処理されます。とにかく、位置からvFocusに向かってベクトルを指しています。これをvDirと呼びます。残念ながら、vPosとvFocusの違いの長さがあります。しかし、vDirベクトルをその長さ(vDir.x/length、vDir.y/length、vDir.z/length、vDir.w/length)で除算すると、で正規化され、

このポニットには、マトリックスの3番目と4番目の列があります。さて、assuem upはまだ(0、1、0、0)またはvUpです。 directionとvUpのクロスプロダクトは、vDirとvUpによって形成された平面に垂直なベクトル(単位長さのベクトル)を生成すると仮定できます。これにより、サイドベクトルまたはvLatが得られます。今、私たちは上向きベクトルを想定していますので、厳密には正しくありません。 vLatとvDirのクロス積を取ることで正確に計算することができ、4つのベクトルすべてが得られます。

vLat.x vUp.x vDir.x vPos.x 
vLat.y vUp.y vDir.y vPos.y 
vLat.z vUp.z vDir.z vPos.z 
vLat.w vUp.w vDir.w vPos.w 

これは厳密には、あなたの(0、1、0、0)に近い点に目を向けると、あなたが問題を取得するよう、完全な答えではありませんが、以下のように、最終的なマトリックスは、このように定義されていますベクトルしかし、それはのほとんどの場合の場合に動作するはずです。

3

私は現時点でJava 3Dを自分で学習しています。私の現在の知識から、回転メソッドは変換をその軸だけの回転に設定します。 したがって、複数の軸について回転を実行する場合は、2番目のTransform3Dを使用する必要があります。
すなわち:それにMath.PIが180度に相当するラジアンの代わり度、使用するためにMath.PI理由として

Transform3D rotation = new Transform3D(); 
Transform3D temp = new Transform3D(); 

rotation.rotX(Math.PI/2); 
temp.rotZ(Math.PI/2); 
rotation.mul(temp); // multiply the 2 transformation matrices together. 

、これがあります。

現在の向きと目的の向きとの間の角度を見つけることはそれほど難しくありません。たとえば、angle()メソッドでVector3fsを使用できます。ベクタは、初期オリエンテーションと意図されたオリエンテーションで設定されます。 しかし、これは角度がどの軸にあるかを教えてくれません。これを行うには、どのセグメントが設定されているかを確認するためにベクトルの検査が必要です。 [もちろん、私がAPIで現在知らないことがあるかもしれません]

+0

ああ...私は、回転させたい各軸に対して別々のTransform3Dが必要ですか?私はTransform3Dの同じインスタンスを使用して、rotX()、rotY()、rotZ()を実行しようとしていました。私はそれを試してみましょう。 – Cuga

+0

回転のために四元数を使用しました。 xとyの周りを回転するだけで、信頼できない問題が発生していました。どうやらジャンピンロックは100%避けられないようです。クォータニオンはこれを避けます。 – Cuga

0

あなたはTransform3Dに回転行列を与えることができます。回転行列計算機をオンラインで使用して回転行列を得ることができます。http://toolserver.org/~dschwen/tools/rotationmatrix.htmlここに私の例があります:

Matrix3f mat = new Matrix3f(0.492403876506104f, 0.586824088833465f, 
      -0.642787609686539f, 0.413175911166535f, 0.492403876506104f, 
      0.766044443118978f, 0.766044443118978f, -0.642787609686539f, 0f); 

    Transform3D trans = new Transform3D(); 

    trans.set(mat); 
関連する問題