【发布时间】:2021-03-24 10:22:12
【问题描述】:
假设我有一个立方体或球形表面。我有一个我想“坐在”这个表面上的对象,即对象的 y 轴应该等于表面的法线。为了渲染,我使用了一个转换,它包含一个位置向量、3 个旋转角度和一个比例向量。
之前,我试图计算标准 向量与法线之间的角度,以获得三个角度:a、b、g。然后,我尝试使用这些角度围绕 i、j 和 k 单位向量旋转对象,使其旋转到与法线相等。
我认为这不起作用,因为 arccos 的范围为 [0, 180]。所以我的问题是:为了将我的对象断言为表面的法线,我需要做什么数学运算?
让我也指定对象围绕法线的旋转无关紧要,我只关心对象是否垂直于表面。
关于规范:我正在使用 Java 和 OpenGL,但这更多是基于数学的问题,所以我认为这并不重要。
这是我正在尝试使用的当前代码:
/**
* generates a vector of rotation to a vector
* @param v - the vector
* @return - a vector containing the x, y, z rotations
*/
public static Vector3f rotationTo(Vector3f v) {
float x = Vector3f.angleBetween(new Vector3f(0, 1, 0), new Vector3f(0, v.y, v.z));
float y = Vector3f.angleBetween(new Vector3f(0, 0, 1), new Vector3f(v.x, 0, v.z));
float z = Vector3f.angleBetween(new Vector3f(0, 1, 0), new Vector3f(v.x, v.y, 0));
return new Vector3f(x, y, z);
}
/**
* determines the angle between two vectors in degrees
* @param v - vector 1
* @param u - vector 2
* @return - the angle between
*/
public static float angleBetween(Vector3f v, Vector3f u) {
return (float) Math.toDegrees(
Math.acos(Vector3f.dot(v, u)
* quickInverseSqrt(v)
* quickInverseSqrt(u))
);
}
/**
* quickly determines the inverse magnitude of a vector using the
* Fast Inverse Square Root formula
* @param v - the vector
* @return - the magnitude
*/
public static float quickInverseSqrt(Vector3f v) {
float val = v.x * v.x + v.y * v.y + v.z * v.z;
float xHalf = 0.5f * val;
int i = Float.floatToIntBits(val);
i = 0x5f3759df - (i >> 1);
val = Float.intBitsToFloat(i);
val *= (1.5f - xHalf * val * val);
return val;
}
【问题讨论】:
标签: 3d opengl-es-2.0 linear-algebra transformation normals