以图像左上角为坐标原点的坐标系,经平移旋转后得到新坐标系,计算原始坐标在新坐标系中的坐标

该博客介绍了如何在二维直角坐标系中进行坐标旋转和平移操作。首先,定义了origin_rotate函数用于坐标原点旋转,接着定义了top_left_translate函数实现坐标系平移及纵坐标的反向。最后,calculate_coords函数综合运用这两个函数,根据两点确定新的坐标系,并进行旋转和平移,计算出新坐标。这个过程涉及到的角度计算和坐标变换对于图形处理和计算机视觉等领域具有重要意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值