0

より簡単にするために編集

それに至るまで、3D空間で3軸で円を回転させる必要があります。問題なくy軸を下に移動しました。ただし、他の 2 つの作業では、円が回転するのではなく、中心点を中心に回転するだけになりました。同様に、回転後にこの円の端の周りの点を見つけることができる必要があります。そうすれば、オブジェクトをそれらのポイントにプロットしたり、そのポイントで効果をレンダリングしたりできます。

私がこれまでに持っているものの例...コンテキストは、コードをグラフィカルにテストするための簡単な場所として、Minecraft の mod にあります。http://puu.sh/38Z6x.jpgコードのテストに 6 ポイントを使用していますが、後で増やすことができます。

これが私がこれまでに持っているコードです-コード-そのgithubなので、コードを同期するたびに変更されますしたがって、私が試したことではなく、私が使用している構造に依存しないでください。前回の同期では、オプションとして球座標系を試していました。

これらの計算を行うためのパフォーマンスのヒントも探しています。これらの計算のいくつかを、何千もの移動オブジェクトの制御に取り組んでいるプロジェクトで実行する予定です。

4

2 に答える 2

0

これが私の単純なクォータニオン クラスです。このチュートリアルにある多くのセマンティクスを使用します。

public class Quaternion {
    public double w, x, y, z;
    public Quaternion(double angleRadian, double x, double y, double z){
        double dAngle=angleRadian/2; //might as well divide by 2 here
        this.w=Math.cos(dAngle);
        this.x=x * Math.sin(dAngle);
        this.y=y * Math.sin(dAngle);
        this.z=z * Math.sin(dAngle);
    }
    public Quaternion(){
        x=y=z=0; w=1;
    }
    public void norm(){
        double magnitude = Math.sqrt(w*w + x*x + y*y + z*z);
        w = w / magnitude;
        x = x /  magnitude;
        y = y / magnitude;
        z = z / magnitude;
    }
    public Quaternion conj(){
        Quaternion ans = new Quaternion();
        ans.set(this);
        ans.conjLocal();
        return ans;
    }
    public void conjLocal(){
        x=-x;
        y=-y;
        z=-z;
    }
    public void set(Quaternion q){
        w=q.w;
        x=q.x;
        y=q.y;
        z=q.z;
    }
    public void set(double w, double x, double y, double z){
        this.w=w;
        this.x=x;
        this.y=y;
        this.z=z;
    }
    public Quaternion mult(Quaternion q){
        Quaternion ans = new Quaternion();
        ans.w = (this.w*q.w - this.x*q.x - this.y*q.y - this.z*q.z);
        ans.x = (this.w*q.x + this.x*q.w + this.y*q.z - this.z*q.y);
        ans.y = (this.w*q.y - this.x*q.z + this.y*q.w + this.z*q.x);
        ans.z = (this.w*q.z + this.x*q.y - this.y*q.x + this.z*q.w);
        return ans;
    }
    public void multLocal(Quaternion q){
        Quaternion temp=this.mult(q);
        this.set(temp);
    }
    public String toString(){ return "<"+w+", "+x+", "+y+", "+z+">"; }
}

vベクトルをクォータニオンで回転しqて結果のベクトルを取得するv'には、次の式を使用する必要があります。

v' = q * v * q.conj()

これは、クォータニオンを中心にベクトル (または位置座標) を回転させるデモです。

public class QuaternionExample {
    public static void main(String[] args) {
        /*
         * Let's say we have a vector <1,0,0>, and we want to rotate it
         * such that the result will be in the other unit axiis: <0,1,0>
         * and <0,0,1>.  Right hand rule applies for rotating about an axis!
         * Convince yourself of the following through mental imagery:
         * 1. For <0,1,0>, we want to rotate <1,0,0> by 90 degrees about the z axis
         * 2. For <0,0,1>, we want to rotate <1,0,0> by 90 degrees about the -y axis (or -90 degrees also works)
         */

        //the quaternion form of a 3d vector is simply <0,Vec3> or <0,x,y,z>
        Quaternion x=new Quaternion(); 
        x.set(0,1,0,0);

        //1, we want <0,1,0>
        Quaternion rot = new Quaternion(Math.PI/2,0,0,1);
        System.out.println( rot.mult(x).mult(rot.conj()) );

        //2, we want <0,0,1>
        rot = new Quaternion(Math.PI/2,0,-1,0);
        System.out.println( rot.mult(x).mult(rot.conj()) );
        rot = new Quaternion(-Math.PI/2,0,1,0);
        System.out.println( rot.mult(x).mult(rot.conj()) );
    }
}

原点を中心にベクトル (または位置座標) を回転させたいと思いました。別のポイント (たとえば、オブジェクトのセントロイドc) を中心に回転させたい場合は、最初にオブジェクトのセントロイドを差し引いてから、結果に追加する必要があります。

v' = q * (v-c) * q.conj() + c
于 2013-06-06T19:20:05.260 に答える