import numpy as np
def origin_rotate(x, y, angle):
"""
以二维直角坐标系为参照系,坐标系基于坐标原点旋转一定角度后,计算新坐标位置
参考:https://www.cnblogs.com/zhoug2020/p/7864898.html
---------
Args:
x : float
原始坐标系横坐标
y : float
原始坐标系纵坐标
angle : float
原坐标系旋转角度, 弧度制
Return:
x1 : float
新坐标系横坐标
y1 : float
新坐标系纵坐标
"""
x1 = x * np.cos(angle) + y * np.sin(angle)
y1 = y * np.cos(angle) - x * np.sin(angle)
return x1, y1
def top_left_translate(x, y, x0, y0):
"""
原坐标系左上角为坐标原点,平移到指定位置(x0, y0)后,以(x0, y0)作为新坐标系的原点,
同时纵坐标反向,计算新坐标位置
原标系:
|-------> x
| (0, 0)
|
y 向下为正方向
平移后:
y 向上为正方向
|
|
--------|--------> x
| (x0, y0)
|
|
---------
Args:
x : float
原始坐标系横坐标
y : float
原始坐标系纵坐标
x0 : float
新坐标系原点在原坐标系的横坐标
y0 : float
新坐标系原点在原坐标系的纵坐标
Return:
x1 : float
新坐标系横坐标
y1 : float
新坐标系纵坐标
"""
x1 = x - x0
y1 = y0 - y # 纵坐标方向改变
return x1, y1
def calculate_coords(x, y, point1, point2):
"""
原坐标系左上角为坐标原点,将坐标系平移,纵坐标反向,坐标系以原点旋转一定角度后,计算新坐标位置
旋转角度,即向量A与向量B间的夹角,方向是A->B
向量A: 水平右方向的单位向量 (0, 0) -> (1, 0)
向量B: 原坐标系平移,纵坐标反向后,计算出点1和点2在新坐标系点位置,此时坐标系横坐标水平向右,纵坐标竖直向上,
然后将新坐标系的 点1 -> 点2 作为向量B
最终坐标系横坐标正方向:点1和点2连线,方向由点1指向点2
最终坐标系纵坐标正方向:点1和点2连线的中垂线,方向向上
最终坐标系坐标原点:点1和点2连线的中点
---------
Args:
x : float
原始坐标系横坐标
y : float
原始坐标系纵坐标
point1 : tuple(float, float)
点1在原坐标系的横纵坐标
point2 : tuple(float, float)
点2在原坐标系的横纵坐标
Return:
x2 : float
新坐标系横坐标
y2 : float
新坐标系纵坐标
"""
# 原坐标系(左上角为坐标原点)平移的新原点位置
x0 = (point1[0] + point2[0]) / 2
y0 = (point1[1] + point2[1]) / 2
# 点1和点2在平移、纵坐标反向坐标系中的新坐标
point1_1 = top_left_translate(*point1, x0, y0)
point2_1 = top_left_translate(*point2, x0, y0)
# 计算 水平右向单位向量 与 点1->点2 夹角
# 余弦公式
A = np.array([1, 0])
B = np.array(point2_1) - np.array(point1_1)
angle = np.arccos(np.sum(A * B) / np.linalg.norm(B)) # 弧度
# 使用向量的外积判断旋转方向,值为正,则顺时针旋转;值为负,则逆时针旋转
cross_product = A[0] * B[1] - A[1] * B[0]
if cross_product < 0:
angle = -angle
# 坐标系绕原点旋转后的新坐标
x1, y1 = top_left_translate(x, y, x0, y0) # 平移 纵坐标反向坐标系
x2, y2 = origin_rotate(x1, y1, angle) # 旋转坐标系
return x2, y2
if __name__ == '__main__':
print(calculate_coords(10, 60, (10, 60), (80, 40)))
print(calculate_coords(80, 40, (10, 60), (80, 40)))
print(calculate_coords(15, 30, (10, 60), (80, 40)))
以图像左上角为坐标原点的坐标系,经平移旋转后得到新坐标系,计算原始坐标在新坐标系中的坐标
于 2022-02-18 13:01:52 首次发布