所以我派生了一个这样的旋转函数:
我想围绕x轴旋转(a,b,c)
a
的值不会改变
这相当于在2d地图中围绕原点旋转(b,c)
对于极坐标中的2d地图,旋转d
度非常简单:
θ = θ + d
对于某个点P(x,y),x = Rcos(θ)
和y = Rsin(θ)
所以让Q为旋转后的点,然后Q = (Rcos(θ + d), Rsin(θ + d))
因为R 2 = x 2 + y 2 且θ= arctan(y / x):
Q =(sqrt(x 2 + y 2 )* cos(arctan(y / x)+ d,sqrt(x 2 + y 2 )* sin(arctan(y / x)+ d)
然后我创建了一个C函数,它给出了一个坐标:a
和rot_amount
(通常为1)它会为我旋转我的坐标。
static void xrotate_coor(t_coor *a, int rot_amount)
{
double d;
double e;
d = a->y;
e = a->z;
if (e == 0 && d == 0)
return ;
if (d == 0)
{
a->y = sqrt(d * d + e * e) * cos(atan(INFIN) + rot_amount * M_PI / 50);
a->z = sqrt(d * d + e * e) * sin(atan(INFIN) + rot_amount * M_PI / 50);
return ;
}
a->y = sqrt(d * d + e * e) * cos(atan(e / d) + rot_amount * M_PI / 50);
a->z = sqrt(d * d + e * e) * sin(atan(e / d) + rot_amount * M_PI / 50);
}
INFIN是我设置为999999的宏。
我不确定它是否正确但是因为使用这个公式我旋转的形状变形了所以我觉得我的逻辑中有一个缺陷......
答案 0 :(得分:3)
您正在经历计算中的错误累积。这是由计算机中数字的表示方式引起的。
在计算机图形中处理此问题的典型方法是保持对象的坐标固定并将它们转换为正在渲染的帧所需的位置。在您的情况下,这意味着不是逐渐旋转对象,而是将对象保持在原始位置,并根据当前显示的位置简单地计算到X轴周围的当前角度的平移。
换句话说,如果您一次翻译360度总共20度,则在第一次迭代中将翻译的坐标显示为20度,在第二次迭代中将翻译的坐标显示为40度,而不是每次实际翻译20度
答案 1 :(得分:1)
......我正在旋转的形状变形......
atan(e / d)
失去了a->y, a->z;
的四象限性质。考虑到使用OP的代码,如果y,z
被否定,则会产生相同的结果。 @Nominal Animal
d = -(a->y);
e = -(a->z);
...
atan(e / d)
而是使用4象限反正切。
double atan2(double y, double x);
atan2
函数计算y
/x
的反正切值,使用两个参数的符号来确定返回值的象限。如果两个参数都为零,则可能会出现域错误。
以下其他建议的改进。
#include <math.h>
static void xrotate_coor(t_coor *a, int rot_amount) {
double d = a->y;
double e = a->z;
double r = hypot(d, e); // vs. sqrt(d * d + e * e)
if (r) {
double angle = atan2(e, d);
angle += rot_amount * (M_PI / 50);
a->y = r * cos(angle);
a->z = r * sin(angle);
}
}