0

我试图在半径为 2 的点 (10,6,10) 周围旋转一个点说 (20,6,30),但到目前为止我一直未能做到这一点。我知道要围绕原点旋转一个点,只需将旋转矩阵与世界矩阵相乘,然后围绕自身旋转一个点,就是将点平移到原点,然后旋转并平移回来,但不知道如何解决这个问题。

4

2 回答 2

3

如果您愿意,我可以将一些 C++ 代码拼凑在一起(远离 D3DX,因为它已被弃用),但我认为自己解决问题是编程的重要组成部分。这是围绕 3d 点 v1 旋转 3d 点 v2 背后的数学原理。希望能帮助到你:

1.) 通过从 v1 中减去 v2 来计算差异向量。存储在 v3 中。

2.) 将 v3 转换为球坐标,由半径、偏航角和俯仰角定义的符号。

3.) 根据需要更改 theta (yaw) 和 phi (pitch) 的值。

4.) 将 v3 转换回笛卡尔 (x, y, z) 坐标并添加 v1 的坐标。这就是 v2 的新位置应该在的地方。

注 1 - 在物理学中,theta 和 phi 的含义是互换的,所以 theta 是俯仰,phi 是偏航。在数学中,theta 是偏航,phi 是俯仰。

注 2 - 偏航、俯仰和横滚描述为:

偏航、俯仰和滚动的图形定义

注 3 - D3DX 上的维基百科:“2012 年,微软宣布 D3DX 将在 Windows 8 SDK 以及 XNA 等其他开发框架中被弃用。D3DX 的数学结构,如向量和矩阵,将与 XNAMath 合并为一个新库:DirectXMath。”

于 2013-11-10T19:03:31.517 回答
0

如果您围绕任意原点坐标旋转对象坐标,则使用半径没有意义,因为在旋转期间半径将保持不变。要在旋转期间使用所需的半径,请确保对象坐标和原点坐标是所需的半径分开。另请注意,在使用欧拉角(相对于球面或四元数)时,您需要一个旋转轴来围绕一个点旋转,否则它无法定义您将在哪个方向上旋转。

如果你愿意做矩阵数学,我就是这样做的(使用伪代码,因为我只知道 OGL):

vec3 translate_around_point
(
    vec3 object_pos,
    vec3 origin_pos,
    vec3 rotation_axis,
    float rotation
)
{
    // get difference
    vec3 difference = object_pos - origin_pos;
    //rotate difference on rotation axis
    mat4 model = rotate(mat4 model(1.0), rotation, rotation_axis);
    vec3 trans = model * vec4(difference, 1.0);
    //add add translation to origin pos
    return origin_pos + trans;
}

您使用此函数的代码如下所示(半径为22.360679626464844):

vec3 object_pos(20.0, 6.0, 30.0); 
vec3 orig_pos(10.0, 6.0, 10.0);
vec3 axis(0.0, 1.0, 0.0); // rotation axis is 'up' in world space
float angle = 90.0;
object_pos = translate_around_point(object_pos, orig_pos, axis, angle);

此外,如果您要在对象位置具有更大高度或倾斜的旋转轴的情况下运行它,那么原点位置可能不再出现在旋转的中心。这没关系,因为如果旋转不在部分轴(x、y 或 z)上旋转,则不会影响该部分的平移。

于 2019-06-01T22:36:50.883 回答