返回

空间点绕轴旋转公式及应用代码

人工智能

理解右手坐标系:空间点绕轴旋转公式

引言

坐标系是三维空间中对象位置和运动的数学工具。右手坐标系是一种常用的坐标系,它使用右手规则来定义轴的正方向。本博客将深入探讨右手坐标系的原理,并提供空间点绕轴旋转公式。

右手坐标系

右手坐标系由三个互相垂直的轴组成:X 轴、Y 轴和 Z 轴。这些轴的正方向由右手规则定义:

  1. 将右手手指并拢,大拇指指向 X 轴正方向。
  2. 食指指向 Y 轴正方向,与大拇指呈 90 度角。
  3. 中指自然弯曲指向 Z 轴正方向,与大拇指和食指呈 90 度角。

空间点绕轴旋转公式

空间点绕轴旋转是指将点绕给定轴旋转一定角度的过程。旋转公式如下:

[x', y', z'] = [x, y, z] * R

其中:

  • [x, y, z] 是空间点在旋转前的坐标。
  • [x', y', z'] 是空间点在旋转后的坐标。
  • R 是旋转矩阵。

旋转矩阵

旋转矩阵是一个 3x3 矩阵,它由旋转轴的单位向量和旋转角度决定。旋转轴的单位向量表示旋转的方向,而旋转角度表示旋转的幅度。

代码示例

以下是用 Python 和 C++ 实现的两个空间点绕轴旋转程序示例:

Python 程序:

import numpy as np

def rotation_matrix(axis, angle):
    """
    Return the rotation matrix for the given axis and angle.

    Args:
        axis: A 3D vector representing the axis of rotation.
        angle: The angle of rotation in radians.

    Returns:
        A 3x3 rotation matrix.
    """
    axis = np.asarray(axis)
    angle = np.asarray(angle)
    axis = axis / np.linalg.norm(axis)

    c = np.cos(angle)
    s = np.sin(angle)
    C = 1 - c

    xs = axis[0] * s
    ys = axis[1] * s
    zs = axis[2] * s

    xC = axis[0] * C
    yC = axis[1] * C
    zC = axis[2] * C

    xyC = axis[0] * axis[1] * C
    xzC = axis[0] * axis[2] * C
    yxC = axis[1] * axis[2] * C

    return np.array([[xC + c, xyC - zs, xzC + ys],
                    [yxC + zs, yC + c, yzC - xs],
                    [xzC - ys, yzC + xs, zC + c]])

def rotate_point(point, axis, angle):
    """
    Rotate a point around an axis by a given angle.

    Args:
        point: A 3D point.
        axis: A 3D vector representing the axis of rotation.
        angle: The angle of rotation in radians.

    Returns:
        The rotated point.
    """
    R = rotation_matrix(axis, angle)
    return np.dot(R, point)

# Define the point to be rotated.
point = np.array([1, 2, 3])

# Define the axis of rotation.
axis = np.array([0, 0, 1])

# Define the angle of rotation.
angle = np.pi / 2

# Rotate the point.
rotated_point = rotate_point(point, axis, angle)

# Print the rotated point.
print(rotated_point)

C++ 程序:

#include <iostream>
#include <cmath>

using namespace std;

struct Vector3 {
    double x, y, z;

    Vector3() : x(0), y(0), z(0) {}
    Vector3(double x, double y, double z) : x(x), y(y), z(z) {}

    Vector3 operator+(const Vector3& other) const {
        return Vector3(x + other.x, y + other.y, z + other.z);
    }

    Vector3 operator-(const Vector3& other) const {
        return Vector3(x - other.x, y - other.y, z - other.z);
    }

    Vector3 operator*(double scalar) const {
        return Vector3(x * scalar, y * scalar, z * scalar);
    }

    double dot(const Vector3& other) const {
        return x * other.x + y * other.y + z * other.z;
    }

    Vector3 cross(const Vector3& other) const {
        return Vector3(y * other.z - z * other.y,
                       z * other.x - x * other.z,
                       x * other.y - y * other.x);
    }

    double length() const {
        return sqrt(x * x + y * y + z * z);
    }

    Vector3 normalize() const {
        double len = length();
        return Vector3(x / len, y / len, z / len);
    }
};

struct Matrix3x3 {
    double m[3][3];

    Matrix3x3() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                m[i][j] = 0;
            }
        }
    }

    Matrix3x3(double m00, double m01, double m02,
              double m10, double m11, double m12,
              double m20, double m21, double m22) {
        m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
        m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
        m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
    }

    Matrix3x3 operator*(const Matrix3x3& other) const {
        Matrix3x3 result;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                result.m[i][j] = 0;
                for (int k = 0; k < 3; k++) {
                    result.m[i][j] += m[i][k] * other.m[k][j];
                }
            }
        }
        return result;
    }

    Vector3 operator*(const Vector3& vector) const {
        Vector3 result;
        for (int i = 0; i < 3; i++) {
            result.x += m[i][0] * vector.x;
            result.y += m[i][1] * vector.y;
            result.z += m[i][2] * vector.z;
        }
        return result;
    }
};

Matrix3x3 rotation_matrix(const Vector3& axis, double angle) {
    Vector3 n = axis.normalize();
    double c = cos(angle);
    double s = sin(angle);
    double C = 1 - c;

    Matrix3x3 result;
    result.m[0][0] = n.x * n.x * C + c;
    result.m[0][1] = n.x * n.y * C - n.z * s;
    result.m[0][2] = n.x * n.z * C + n.y * s;
    result.m[1][0] = n.y * n.x * C + n.z * s;
    result.m[1][1] = n.y * n.y * C + c;
    result.m[1][2] = n.y * n.z * C - n.x * s;
    result.m[2][0] = n.z * n.x * C - n.y * s;
    result.m[2][1] = n.z * n.y * C + n.x * s;
    result.m[2][2] = n.z * n.z * C + c;

    return result;
}

Vector3 rotate_point(const Vector3& point, const Vector3& axis, double angle