三维坐标的旋转其实挺容易理解的。
首先需要有个旋转中心 O ( x , y , z ) O(x,y,z) O(x,y,z),
其次是我们的旋转点 P ( x 1 , y 1 , z 1 ) P(x_1,y_1,z_1) P(x1,y1,z1),
那么可知旋转点 P P P的相对坐标为 P ′ ( x 1 − x , y 1 − y , z 1 − z ) P'(x_1-x,y_1-y,z_1-z) P′(x1−x,y1−y,z1−z)
此时我们开始旋转。因为坐标系有三个轴,那么旋转其实就是绕着任意的两个轴进行旋转(当然三个轴也是可以的,但是两个轴足以实现三个轴的效果了)
绕着某一轴进行旋转的过程中,该轴对应的坐标是不产生变化的,那么实际上变化的坐标就是在一个二维平面上,此时就又转化为二维旋转问题。
假设已知 A ( x 1 , y 1 ) A(x_1,y_1) A(x1,y1),现围绕原点 O ( 0 , 0 ) O(0,0) O(0,0)旋转 β \beta β角度,求现在位置 B ( x 2 , y 2 ) B(x_2,y_2) B(x2,y2):
首先设 A O AO AO与 x x x轴夹角为 α \alpha α,那么 B O BO BO与 x x x轴夹角为 α + β \alpha+\beta α+β,可知:
x 2 = x 1 2 + y 1 2 ∗ c o s ( α + β ) x_2=\sqrt{x_1^2+y_1^2}*cos(\alpha+\beta) x2=x12+y12∗cos(α+β)
y 2 = x 1 2 + y 1 2 ∗ s i n ( α + β ) y_2=\sqrt{x_1^2+y_1^2}*sin(\alpha+\beta) y2=x12+y12∗sin(α+β)
利用两角公式展开:
x 2 = x 1 2 + y 1 2 ( c o s ( α ) c o s ( β ) − s i n ( α ) s i n ( β ) ) x_2=\sqrt{x_1^2+y_1^2}(cos(\alpha)cos(\beta)-sin(\alpha)sin(\beta)) x2=x12+y12(cos(α)cos(β)−sin(α)sin(β))
y 2 = x 1 2 + y 1 2 ( s i n ( α ) c o s ( β ) + c o s ( α ) s i n ( β ) ) y_2=\sqrt{x_1^2+y_1^2}(sin(\alpha)cos(\beta)+cos(\alpha)sin(\beta)) y2=x12+y12(sin(α)cos(β)+cos(α)sin(β))
化简:
x 2 = x 1 c o s ( β ) − y 1 s i n ( β ) x_2=x_1cos(\beta)-y_1sin(\beta) x2=x1cos(β)−y1sin(β)
y 2 = y 1 c o s ( β ) + x 1 s i n ( β ) y_2=y_1cos(\beta)+x_1sin(\beta) y2=y1cos(β)+x1sin(β)
//三维坐标
struct Position{
float x;
float y;
float z;
};
//二维坐标旋转
void rotation(
float &x,
float &y,
float degree)
{
if(degree==0)
return;
float tempx = x * cos(degree) - y * sin(degree);
float tempy = y * cos(degree) + x * sin(degree);
x = tempx;
y = tempy;
}
//三维坐标旋转
void rotation(
Position &point,
Position origin,
float degreeX,
float degreeY,
float degreeZ)
{
//求出到旋转点的相对坐标
point.x -= origin.x;
point.y -= origin.y;
point.z -= origin.z;
//分别绕X、Y、Z三轴进行旋转
rotation(point.y,point.z,degreeX);
rotation(point.x,point.z,degreeY);
rotation(point.x,point.y,degreeZ);
//根据旋转点转换回原来的坐标系
point.x += origin.x;
point.y += origin.y;
point.z += origin.z;
}