有没有大佬帮忙解决一个数学问题:求指定点旋转后的坐标

2

已知 A 点、B 点的坐标,以 A 点为中心、AB 为半径,旋转 B 点任意角度,求旋转后 B 点的坐标。

哪位大佬能帮解决一下这个问题。

ava
火狐狸

2023-1-12

1

这是图形学的常见算法。

公式

已知点 A(x, y),绕指定点 C(x, y) 旋转弧度 a,则旋转后的点 B(x, y) 坐标为:

\[ \begin{align*} B.x &= (A.x - C.x) * cos(a) - (A.y - C.y) * sin(a) + C.x \\ B.y &= (A.x - C.x) * sin(a) + (A.y - C.y) * cos(a) + C.y \end{align*} \]

测试代码

完整代码如下:

// 程序:求指定点旋转后的坐标
//
#include <graphics.h>
#include <conio.h>
#include <math.h>

const double PI = 3.1415926536;

// 将点 d 围绕点 center 旋转弧度 a,返回旋转后的坐标
POINT Rotate(POINT center, POINT d, double a)
{
	a = -a;		// 注意,屏幕坐标 y 轴向下,故旋转弧度取反
	POINT r;
	r.x = (d.x - center.x) * cos(a) - (d.y - center.y) * sin(a) + center.x;
	r.y = (d.x - center.x) * sin(a) + (d.y - center.y) * cos(a) + center.y;
	return r;
}

// 主函数
int main()
{
	initgraph(640, 480);

	// 定义点 A 和 B
	POINT A, B;
	A.x = 300; A.y = 200;
	B.x = 400; B.y = 120;

	line(A.x, A.y, B.x, B.y);
	POINT b = Rotate(A, B, PI / 2);

	setlinecolor(RED);
	line(A.x, A.y, b.x, b.y);

	_getch();
	return 0;
}

推导过程

公式 1:绕原点旋转

已知点 A(x, y),绕原点 O 旋转弧度 a,求旋转后的点 B(x, y) 坐标。设 OA 长度为 r,与 X 轴夹角为 θ,则:

\[ \begin{align*} A.x &= r * cos(θ) \\ A.y &= r * sin(θ) \\ B.x &= r * cos(θ + a) \\ B.y &= r * sin(θ + a) \end{align*} \]

通过三角函数展开得到:

\[ \begin{align*} B.x &= r * cos(θ + a) = r * cos(θ) * cos(a) - r * sin(θ) * sin(a) = A.x * cos(a) - A.y * sin(a) \\ B.y &= r * sin(θ + a) = r * sin(θ) * cos(a) + r * cos(θ) * sin(a) = A.x * sin(a) + A.y * cos(a) \end{align*} \]

写成矩阵形式:

\[ \begin{bmatrix} cos(a) & -sin(a) & 0\\ sin(a) & cos(a) & 0\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} A.x\\ A.y\\ 1 \end{bmatrix} = \begin{bmatrix} B.x\\ B.y\\ 1 \end{bmatrix} \]

公式 2:坐标平移

已知点 A(x, y),令 A 在 x 方向移动 m,在 y 方向移动 n,求移动后的点 B(x, y) 坐标:

\[ \begin{align*} B.x &= A.x + m \\ B.y &= A.y + n \end{align*} \]

写成矩阵形式:

\[ \begin{bmatrix} 1 & 0 & m\\ 0 & 1 & n\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} A.x\\ A.y\\ 1 \end{bmatrix} = \begin{bmatrix} B.x\\ B.y\\ 1 \end{bmatrix} \]

公式 3:绕指定点旋转

已知点 A(x, y),绕指定点 C(x, y) 旋转弧度 a,求旋转后的点 B(x, y) 坐标。

求解过程:先将 A 点平移到原点,然后使 A 点绕原点旋转,旋转完毕后再将 A 点平移回来。可依据公式 1、2 的矩阵形式得:

\[ \begin{bmatrix} 1 & 0 & C.x\\ 0 & 1 & C.y\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} cos(a) & -sin(a) & 0\\ sin(a) & cos(a) & 0\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} 1 & 0 & -C.x\\ 0 & 1 & -C.y\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} A.x\\ A.y\\ 1 \end{bmatrix} = \begin{bmatrix} cos(a) & -sin(a) & -C.x*cos(a)+C.y*sin(a)+C.x\\ sin(a) & cos(a) & -C.x*sin(a)-C.y*cos(a)+C.y\\ 0 & 0 & 1 \end{bmatrix} * \begin{bmatrix} A.x\\ A.y\\ 1 \end{bmatrix} = \begin{bmatrix} B.x\\ B.y\\ 1 \end{bmatrix} \]

可得最终公式:

\[ \begin{align*} B.x &= (A.x - C.x) * cos(a) - (A.y - C.y) * sin(a) + C.x \\ B.y &= (A.x - C.x) * sin(a) + (A.y - C.y) * cos(a) + C.y \end{align*} \]
ava
慢羊羊

2023-1-13

1 给村长点赞,每个回答都质量极高。 -  huidong  2023-1-13
1 3.1415926536 村长的这个周率最后是 6 旋转角度是 90 度的时候画直线,直线不直,会多一点点3.1415926535(用这个圆周率, 旋转用 PI /2 90 度角的直线不会歪) -  Margoo  2023-1-14
十分感谢😃  本人是的初二学生,这些图形算法不是很懂,感谢大佬指点 -  火狐狸  2023-1-14
0

我自己推导了一个公式,你可以再验证一下:

对于A(m, n), B(x, y), 旋转角为d:

旋转后B' ( (x-m)cos(d) - (y-n)sin(d) + m , (x-m)sin(d) - (y-n)cos(d) + n )

这个式子中d就表示那个旋转角,无关其单位,你只需要得到该单位下对应的三角函数值就行了

ava
Aurora_Ray

2023-1-13

技术讨论社区