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

2

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

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

ava
火狐狸

2023-1-12

1

这是图形学的常见算法。

公式

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

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
# 测试代码 完整代码如下:
// 程序:求指定点旋转后的坐标
//
#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 轴夹角为 θ,则:

A.x = r * cos(θ) A.y = r * sin(θ) B.x = r * cos(θ + a) B.y = r * sin(θ + a)
通过三角函数展开得到:
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)
写成矩阵形式:
┌                 ┐   ┌   ┐   ┌   ┐
│cos(a) -sin(a)  0│   │A.x│   │B.x│ 
│sin(a)  cos(a)  0│ * │A.y│ = │B.y│ 
│  0       0     1│   │ 1 │   │ 1 │ 
└                 ┘   └   ┘   └   ┘

 公式 2:坐标平移

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

B.x = A.x + m B.y = A.y + n
写成矩阵形式:
┌       ┐   ┌   ┐   ┌   ┐
│1  0  m│   │A.x│   │B.x│ 
│0  1  n│ * │A.y│ = │B.y│ 
│0  0  1│   │ 1 │   │ 1 │ 
└       ┘   └   ┘   └   ┘

 公式 3:绕指定点旋转

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

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

┌         ┐   ┌                 ┐   ┌         ┐   ┌   ┐   ┌                                         ┐   ┌   ┐
│1  0  C.x│   │cos(a) -sin(a)  0│   │1  0 -C.x│   │A.x│   │cos(a) -sin(a) -C.x*cos(a)+C.y*sin(a)+C.x│   │B.x│ 
│0  1  C.y│ * │sin(a)  cos(a)  0│ * │0  1 -C.y│ * │A.y│ = │sin(a)  cos(a) -C.x*sin(a)-C.y*cos(a)+C.y│ = │B.y│ 
│0  0   1 │   │  0       0     1│   │0  0   1 │   │ 1 │   │  0       0                1             │   │ 1 │ 
└         ┘   └                 ┘   └         ┘   └   ┘   └                                         ┘   └   ┘

可得最终公式:

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
ava
慢羊羊

2023-1-13

1 给村长点赞,每个回答都质量极高。 - huidong 2023-1-13
1 3.1415926536 村长的这个周率最后是 6 旋转角度是 90 度的时候画直线,直线不直,会多一点点3.1415926535(用这个圆周率, 旋转用 PI /2 90 度角的直线不会歪) - 舞乐耶 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

技术讨论社区