過去幾天我一直在嘗試爲3D圖形程序的用戶界面製作虛擬軌跡球的工作實現。但我遇到了麻煩。虛擬軌跡球實施
看着數字和許多測試的問題似乎是我的四元數的實際連接,但我不知道也不這麼認爲。我從來沒有使用四元或虛擬軌跡球,這對我來說都是新的。我使用JOGL提供的Quaternion
類。我嘗試着製作自己的作品(或者至少據我所知),但它是一個完整的混亂,所以我只用了JOGL。
當我不連接四元數時,我所看到的輕微旋轉似乎是我想要的,但當然,當它只是向任何方向移動時都很難。此代碼基於OpenGL wiki上的Trackball Tutorial。
當我使用Quaternion
類的mult (Quaternion q)
方法時,圖幾乎不會移動(甚至小於不試圖連接四元數)。
當我嘗試Quaternion class's
添加(Quaternion q)方法爲它的樂趣我得到的東西,至少旋轉圖,但不是以任何連貫的方式。當我移動鼠標時,它會隨機出現並隨機旋轉。偶爾我會得到完全充滿NaN的四元數。
在我的代碼中,我不會顯示其中的任何一個,我迷失在與我的四元數做什麼。我知道我想擴大他們,因爲據我所知,這是他們如何連接。但就像我說過我沒有成功,我假設在我的代碼中的其他地方。
無論如何,我的設置有Trackball
類與public Point3f projectMouse (int x, int y)
方法和public void rotateFor (Point3f p1, Point3f p2)
,其中Point3f
是我做的類。另一個類Camera
有一個public void transform (GLAutoDrawable g)
方法,它將根據軌跡球的四元數調用OpenGL方法進行旋轉。
下面的代碼:
public Point3f projectMouse (int x, int y)
{
int off = Screen.WIDTH/2; // Half the width of the GLCanvas
x = x - objx_ - off; // obj being the 2D center of the graph
y = off - objy_ - y;
float t = Util.sq(x) + Util.sq(y); // Util is a class I made with
float rsq = Util.sq(off); // simple some math stuff
// off is also the radius of the sphere
float z;
if (t >= rsq)
z = (rsq/2.0F)/Util.sqrt(t);
else
z = Util.sqrt(rsq - t);
Point3f result = new Point3f (x, y, z);
return result;
}
這裏的旋轉法:
public void rotateFor (Point3f p1, Point3f p2)
{
// Vector3f is a class I made, I already know it works
// all methods in Vector3f modify the object's numbers
// and return the new modify instance of itself
Vector3f v1 = new Vector3f(p1.x, p1.y, p1.z).normalize();
Vector3f v2 = new Vector3f(p2.x, p2.y, p2.z).normalize();
Vector3f n = v1.copy().cross(v2);
float theta = (float) Math.acos(v1.dot(v2));
float real = (float) Math.cos(theta/2.0F);
n.multiply((float) Math.sin(theta/2.0F));
Quaternion q = new Quaternion(real, n.x, n.y, n.z);
rotation = q; // A member that can be accessed by a getter
// Do magic on the quaternion
}
編輯:
我越來越近,我發現了一些簡單的錯誤。
1:JOGL實現對待W¯¯爲實數,而不是X,我使用X爲真實
2:我不開始與四元數1 + 0I + 0j的+ 0K
3 :我沒有四元數轉換成軸/角度的OpenGL
4:我沒有角度轉換成度的OpenGL
同樣如馬庫斯指出我沒有歸一化的法線,當我做我看不到太多變化,認爲這很難說,他是對的。
現在的問題是,當我做整個事情時,圖像與你一樣激烈的震動永遠不會相信。它(有點)朝着你想要的方向移動,但是癲癇發作太激烈了,不能做任何事情。
這裏是我的新代碼有幾個名稱的變化:
public void rotate (Vector3f v1, Vector3f v2)
{
Vector3f v1p = v1.copy().normalize();
Vector3f v2p = v2.copy().normalize();
Vector3f n = v1p.copy().cross(v2p);
if (n.length() == 0) return; // Sometimes v1p equals v2p
float w = (float) Math.acos(v1p.dot(v2p));
n.normalize().multiply((float) Math.sin(w/2.0F));
w = (float) Math.cos(w/2.0F);
Quaternion q = new Quaternion(n.x, n.y, n.z, w);
q.mult(rot);
rot_ = q;
}
下面是OpenGL的代碼:
Vector3f p1 = tb_.project(x1, y1); // projectMouse [changed name]
Vector3f p2 = tb_.project(x2, y2);
tb_.rotate (p1, p2);
float[] q = tb_.getRotation().toAxis(); // Converts to angle/axis
gl.glRotatef((float)Math.toDegrees(q[0]), q[1], q[2], q[3]);
的原因名稱更改是因爲我刪除了Trackball
課堂上的一切,並開始過度。可能不是最棒的主意,但是哦。
EDIT2:
我可以相當好肯定地說,沒有錯與投影到球體。
我也可以說,就整個事情而言,似乎是問題的VECTOR。角度看起來很好,但矢量似乎跳動。
EDIT3:
的問題是兩個四元數乘法,我可以證實,一切按預期工作。在乘法運算過程中,某些東西會與軸發生w!!