这是线性代数稍微长一点的情况之一。你根本不需要三角函数。三角函数全是关于角度的,你正在做的是将直角坐标转换成角度,然后再转换成直角坐标。这两次转换是不必要的。
我们来定义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:这没有帮助。问题是角度的选择。使用四元数是获得相同答案的另一种技术。 –