這是線性代數稍微長一點的情況之一。你根本不需要三角函數。三角函數全是關於角度的,你正在做的是將直角座標轉換成角度,然後再轉換成直角座標。這兩次轉換是不必要的。
我們來定義v = p2-p1。假設你的圓柱沿Z軸從(0,0,0)到(0,0,1)。我們正努力創造一個矩陣A爲我們提供瞭如下改造:
A * (0, 0, 1) = v
那麼,一旦你寫出來這樣的,它看起來非常簡單,不是嗎!因爲通過基向量右乘矩陣給我們一個列向量。所以v必須是矩陣的其中一列。
A = [ ? ? v.x ]
[ ? ? v.y ]
[ ? ? v.z ]
現在我們只選擇那些被歸一化和正交至v另外兩個列向量,所以我們保持激光器的橫截面形狀。這很簡單。下面是一些代碼,因爲它將用GLSL編寫(你可以在C++中使用glm或在JavaScript中使用gl-matrix來獲得類似的語法)。
mat3 create_laser_matrix(vec3 v) {
// Find a vector, ref, not parallel to v
vec3 vmag = abs(v);
vec3 ref;
if (vmag.x <= vmag.y && vmag.x <= vmag.z) {
ref = vec3(1.0, 0.0, 0.0);
} else if (vmag.y <= vmag.z) {
ref = vec3(0.0, 1.0, 0.0);
} else {
ref = vec3(0.0, 0.0, 1.0);
}
// Use ref to create two unit vectors, u1, u2, so {v, u1, u2} are orthogonal
vec3 utemp = cross(v, ref);
vec3 u1 = normalize(cross(v, utemp));
vec3 u2 = normalize(cross(v, u1));
return mat3(u1, u2, v);
}
爲了擴大對數學:三角允許我們的角度和直角座標和反之亦然之間進行轉換,但事實證明,我們並不需要這樣做的。一個「旋轉矩陣」只是一種正交矩陣(一個具有行列式1而不是-1),正交矩陣就是列向量正交的矩陣,這就意味着任意兩列的點積向量是零。沒有三角法需要。我們並不完全在正交矩陣之後,因爲我們需要「伸出」激光來連接兩個點,但大部分相同的數學運算也適用。
使用四元數並將其轉換爲旋轉矩陣 –
@willywonka_dailyblah:這沒有幫助。問題是角度的選擇。使用四元數是獲得相同答案的另一種技術。 –