平面或空间中任意点的旋转

平面或空间中任意点的旋转

自己琢磨出来的。若有错误请指出。谢谢!

rotate

1. 旋转2D

假设平面上有一个点P(x,y),旋转任意角度β,求旋转后的点P(x,y)

设平面坐标系上有一个半径为r的圆,圆心位于原点O。圆与x轴正坐标的交点为P0(x0,y0)

P0={x0=ry0=0

将点P0旋转任意角度α弧度得任意点P1(x1,y1),那么点P1(x1,y1)的坐标该怎么通过计算获得?

P1={x1=r×cos(α)y1=r×sin(α)

现在将另一任意点P2(x2,y2)相对于点P1(x1,y1)旋转任意角度β,那么点P2(x2,y2)的坐标该怎么通过计算获得?

P2={x2=r×cos(α+β)y2=r×sin(α+β)

使用三角函数的和角公式把点P2的坐标公式展开得:

P2={x2=r×cos(α+β)=r×cosα×cosβr×sinα×sinβy2=r×sin(α+β)=r×sinα×cosβ+r×cosα×sinβ

P1得坐标带入上面P2的坐标展开式,则有:

P2={x2=x1×cosβy1×sinβy2=y1×cosβ+x1×sinβ

总结:对于平面上任意点P(x,y),旋转任意角度β后,得到的点P(x,y)为:

P={x=x×cosβy×sinβy=y×cosβ+x×sinβ

三角函数和差公式

sin(α+β)=sinαcosβ+cosαsinβsin(αβ)=sinαcosβcosαsinβcos(α+β)=cosαcosβsinαsinβcos(αβ)=cosαcosβ+sinαsinβ

2. 旋转3D

假设平面上有一个点P(x,y,z),绕x轴、y轴和z轴相对于原点旋转任意角度αβγ,求旋转后的点P(x,y,z)

按照类似于2D的情况来考虑此问题。该问题可以分解为分别在yz平面,xz平面和xy平面内相对于原点旋转。那么,有以下结论:

yz平面内绕x轴相对于原点旋转α角度旋转:

(1)x=x(2)y=y×cosαz×sinα(3)z=z×cosα+z×sinα

xz平面内绕y轴相对于原点旋转β角度旋转:

(4)x=x×cosβz×sinβ(5)y=y(6)z=z×cosβ+x×sinβ

xy平面内绕z轴相对于原点旋转γ角度旋转:

(7)x=x×cosγy×sinγ(8)y=y×cosγ+x×sinγ(9)z=z

注:绕z轴旋转,理解为点Pxy平面内的投影,并绕原点旋转。其余的情况类似。

3. 代码

这里使用Python语言来编写上面两种旋转的代码,如下:

import math


def rotate_2d(x: int | float,
              y: int | float,
              rad: int | float) -> (float, float):
    """
    Rotate a point around orientation at any given radian.

    :param x: X scale of point.
    :param y: Y scale of point.
    :param rad: Radian value to be rotated.
    :return: A new point has been rotated by rad radian.
    :raise: None.

    """
    rad = float(rad)

    r_x: float = (x * math.cos(rad)) - (y * math.sin(rad))
    r_y: float = (y * math.cos(rad)) + (x * math.sin(rad))

    return r_x, r_y


def rotate_3d(x: int | float,
              y: int | float,
              z: int | float,
              ax: float,
              ay: float,
              az: float) -> (float, float, float):
    """
    Rotate a point in 3d space around orientation at any given radian.

    :param x: X scale of point.
    :param y: Y scale of point.
    :param z: Z scale of point.
    :param ax: Radian value to be rotated around orientation x.
    :param ay: Radian value to be rotated around orientation y.
    :param az: Radian value to be rotated around orientation z.
    :return: A new point has been rotated by rad radian.
    :raise: None.

    """
    ax = float(ax)
    ay = float(ay)
    az = float(az)

    # rotate around axis x
    r_x = x
    r_y = y * math.cos(ax) - z * math.sin(ax)
    r_z = z * math.cos(ax) + y * math.sin(ax)
    x, y, z = r_x, r_y, r_z

    # rotate around axis y
    r_y = y
    r_x = x * math.cos(ay) - z * math.sin(ay)
    r_z = z * math.cos(ay) + x * math.sin(ay)
    x, y, z = r_x, r_y, r_z

    # rotate around axis z
    r_z = z
    r_x = x * math.cos(az) - y * math.sin(az)
    r_y = y * math.cos(az) + x * math.sin(az)

    return r_x, r_y, r_z


def radian(degree: int | float):
    """
    Convert radian value in to radian value.

    :param degree: Degree value to be converted.
    :return: Radian value.
    :raise: None.
    """
    return degree * math.pi / 180.0


if __name__ == "__main__":

    def main():
        x = 1.0
        y = 0.0

        for i in range(360+1):
            p = rotate_2d(x, y, radian(i))
            print("{:>3d} degree, ".format(i), '(x: {:+.3f}, y:{:+.3f})'.format(*p))

        return


    main()


参考资料:

Typora超全数学公式全集
Typora公式块左对齐

posted @   kokiafan  阅读(173)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示