2015-01-16 61 views
0

我已經制作了一個Java程序,它顯示投影到二維視圖上的三維空間中的線條,到目前爲止,它一直工作得很好。我試圖讓這個'世界'圍繞任何軸旋轉相機的位置,但現在我遇到了一些問題。關於三維空間中的樞軸點的旋轉點

public void rotate(){ 
    float ax = main.angleX; //main = camera 
    float ay = main.angleY; 
    float az = main.angleZ; 
    for(Line3d line : lines){ //all lines in the world 
     Vector3d start = Vector3d.Vector3dPMinus(line.start, main.getPoint()); //vetor value of starting point of line - camera's position 
     Vector3d end = Vector3d.Vector3dPMinus(line.end, main.getPoint()); 
     start.rotate(ax, ay, az); 
     end.rotate(ax, ay, az); //rotate each vector 
     line.start = Point3d.pointFromVector3d(start).add(main.getPoint()); 
     line.end = Point3d.pointFromVector3d(end).add(main.getPoint()); //vectors back into points 
    } 
} 

旋轉功能:

public Vector3d rotate(float ax, float ay, float az){ 
    Math.toRadians(ax *= 90); 
    Math.toRadians(ay *= 90); 
    Math.toRadians(az *= 90); 
    y = (float) (y * Math.cos(ax) - z * Math.sin(ax)); 
    z = (float) (y * Math.sin(ax) + z * Math.cos(ax)); 
    x = (float) (x * Math.cos(ay) + z * Math.sin(ay)); 
    z = (float) (z * Math.cos(ay) - x * Math.sin(ay)); 
    x = (float) (x * Math.cos(az) - y * Math.sin(az)); 
    y = (float) (x * Math.sin(az) + y * Math.cos(az)); 
    return this; 
} 

我已經把它繞x軸每秒3次,並顯示正是我希望它也開始轉動之前,但一旦它開始旋轉,通常只有一條水平線有一些不可識別的混亂。

我用於旋轉的方法不正確嗎?有沒有更好的方法來做到這一點?

+0

你說你想圍繞*任何*軸旋轉世界,但是你的代碼似乎試圖圍繞特定於相機的軸執行旋轉。也許在攝像機視角方向?如果是這樣的話,爲什麼不旋轉相機呢? –

回答

0

圍繞3軸旋轉3d矢量並不像人們想象的那麼微不足道。你可能試圖做的事是旋轉所謂的Euler Angles。您應該熟悉matrices以使用3d空間。我檢查了你的旋轉,他們應該工作得很好。但是你應該牢記以下幾點:當你圍繞一個角度旋轉時。以下旋轉受前一次旋轉的影響。你也在旋轉旋轉軸。 爲了避免這種行爲,一個醜陋的可能性是圍繞自由軸旋轉。而且當你首先圍繞X軸旋轉時。您反轉y軸,然後圍繞此y'旋轉。當你圍繞z旋轉時,你需要旋轉z軸,反轉x和y旋轉,然後圍繞這個z'旋轉。當你這樣做時,你總是可以圍繞你的世界座標系旋轉。你應該使用一些數學庫來實現這一點。它讓你的生活變得更輕鬆。當你想自己編碼時。你需要一個適當的矩陣類和乘法矩陣和矢量和一些反演方法。

0

您的方法似乎採取了合理的一般形式。它看起來像是在相對於當前相機位置旋轉線端點,這是正確的,並且您正在執行的三個特定旋轉也可以是正確的(但在下面看到)。

但是,三個Math.toRadians()調用不能做任何有用的事情,因爲您忽略了它們的結果。此外,表達式ax *= 90及其同伴看起來非常可疑:是ax,ayaz真的表示爲四分之一圈的分數嗎?這似乎令人懷疑,如果是這種情況,那麼你會想乘以Math.PI/2並跳過toRadians()。在另一方面,如果他們以度則rotate()以下版本是正確的一個合理的axay定義,az,並一些可能Vector3D實現:

public Vector3d rotate(double ax, double ay, double az){ 
    ax = Math.toRadians(ax); 
    ay = Math.toRadians(ay); 
    az = Math.toRadians(az); 
    y = (float) (y * Math.cos(ax) - z * Math.sin(ax)); 
    z = (float) (y * Math.sin(ax) + z * Math.cos(ax)); 
    x = (float) (x * Math.cos(ay) + z * Math.sin(ay)); 
    z = (float) (-x * Math.sin(ay) + z * Math.cos(ay)); 
    x = (float) (x * Math.cos(az) - y * Math.sin(az)); 
    y = (float) (x * Math.sin(az) + y * Math.cos(az)); 
    return this; 
} 

總體而言,儘管如此,我也有點懷疑爲此目的的ax,ayaz的正確性。尤其要注意的是,不能只是獨立地累積單獨的x,y和z旋轉增量,因爲生成的聚合旋轉很大程度上取決於執行增量旋轉的順序。此外,即使ax,ayaz正確地描述了相機的方向,向世界應用相同的旋轉也不太可能是您真正想要做的。

儘管如此,但我並沒有看到任何理由說明爲什麼你的代碼會像你描述的那樣扭曲模型。我不認爲它會應用你想要的旋轉(即使是我的建議修正),但失真的原因可能在其他地方。

+0

我意識到ax * = 90問題,ax,ay和az實際上是四分之一圓的分數。我將Math.toRadians改爲手動執行,但有一個小問題。它或多或少可以用於沿着z軸旋轉,儘管越來越小/遠離(idk),但是對於x軸,它不能正確顯示,而對於y,它完全消失。 –