再会。
任务:给定两个三维向量 - A 和 B。这些向量相互正交且长度等于 1。编写一个方法,在由向量 A 和 B 定义的平面中旋转向量 A。从向量 A 到向量 B 的旋转被认为是正的。该方法适用于度数,而不是弧度。y 轴指向上方。
我如何尝试解决问题:我创建了一个 Vector3D 类并在其中包含以下方法
void Vector3D::rotate(Vector3D* b, double angle) {
// Находим координаты вектора, в локальной системе координат задаваемой векторами a и b.
double localX = cos(degreeToRadian(angle));
double localY = sin(degreeToRadian(angle));
// умножаем векторы а и b на скаляры - длины компонентов результатирующего вектора
double newXA = x * localX;
double newYA = y * localX;
double newZA = z * localX;
double newXB = b->x * localY;
double newYB = b->y * localY;
double newZB = b->z * localY;
// складываем полученные векторы
x = newXA + newXB;
y = newYA + newYB;
z = newZA + newZB;
}
在条件向量 A 上调用此向量。条件向量 B 和旋转角度作为参数传递。
什么不起作用: 测试
void print(Vector3D* vector) {
printf("vector(x=%f;y=%f;z=%f)\n", vector->getX(), vector->getY(), vector->getZ());
}
int main(void) {
Vector3D a(-1,1,-1);
a.setLength(1);
Vector3D b(1,1,1);
b.setLength(1);
a.rotate(&b, 45);
print(&a);
system("pause");
return 0;
}
期望:向量(x=-0.000000;y=1.000000;z=-0.000000)
我得到:向量(x=-0.000000;y=0.816497;z=-0.000000)
由于某种原因,矢量的长度在旋转后会发生变化。请告诉我错误在哪里。
在这种情况下,使用SLERP(球面插值)很方便,对于正交向量来说特别简单
使用范围 t = 0..4 对应于从 0 到 2*Pi 的角度
PS 仔细观察表明使用了这种方法,但是,上面示例中的向量 a 和 b 不是正交的 - 这从它们的标量积非零这一事实中可以看出
一般来说,正如他们在上面的评论中所写的那样,错误在于输入的数据不正确。我扩展了方法。现在它的工作原理如下:它在由向量 A 和 B 给出的平面中将向量 A 旋转角度角度。角度以度为单位。正旋转是从向量 A 到向量 B 的方向上的旋转。