三维坐标数学计算公式

三维坐标公式记录:

import math

import numpy as np


def euclidean_distance(p1, p2) -> float:
    """
    三维向量欧几里得距离
    Args:
        p1: [x, y, z, confidence]
        p2: [x, y, z, confidence]

    Returns:
        两个向量的欧几里得距离[浮点数]
    """
    return np.linalg.norm(p1[:3] - p2[:3])


def calculate_angle_degree(a1, a2) -> float:
    # 两边向量的夹角
    # 创建向量a和b
    a = np.array(a1)
    b = np.array(a2)

    # 计算两个向量的模
    l_a = np.sqrt(a.dot(a))
    l_b = np.sqrt(b.dot(b))
    print("向量的模:", l_a, l_b)

    # 向量的点积
    dian = a.dot(b)
    print("向量的点积=", dian)

    # 计算夹角的cos值
    cos_ = dian / (l_a * l_b)
    print("夹角的cos值=", cos_)

    # 求得夹角(弧度)
    angle_hu = np.arccos(round(cos_, 1))
    print(f"弧度 = ", angle_hu)

    # 转换为角度
    angle_d = angle_hu * 180 / np.pi
    print(f"夹角 = ", angle_d)

    return angle_d


def get_vector(a, b):
    """获取空间向量

    Args:
        a: [x1, y1, z1]
        b: [x2, y2, z2]

    Returns:
        [x2-x1, y2-y1, z2-z1]
    """
    return [b1 - a1 for a1, b1 in zip(a, b)]


def cal_angle(point_a, point_b, point_c):
    """
    根据三点坐标计算夹角

                  点a
           点b ∠
                   点c
    Args:
        point_a: 数据类型为list,二维坐标形式[x、y]或三维坐标形式[x、y、z]
        point_b: 数据类型为list,二维坐标形式[x、y]或三维坐标形式[x、y、z]
        point_c: 数据类型为list,二维坐标形式[x、y]或三维坐标形式[x、y、z]

    Returns:
        返回角点b的夹角值

    --
        数学原理:
        设m,n是两个不为0的向量,它们的夹角为<m,n> (或用α ,β, θ ,..,字母表示)

        1、由向量公式:cos<m,n>=m.n/|m||n|

        2、若向量用坐标表示,m=(x1,y1,z1), n=(x2,y2,z2),

        则,m.n=(x1x2+y1y2+z1z2).

        |m|=√(x1^2+y1^2+z1^2), |n|=√(x2^2+y2^2+z2^2).

        将这些代入②得到:

        cos<m,n>=(x1x2+y1y2+z1z2)/[√(x1^2+y1^2+z1^2)*√(x2^2+y2^2+z2^2)]

        上述公式是以空间三维坐标给出的,令坐标中的z=0,则得平面向量的计算公式。

        两个向量夹角的取值范围是:[0,π].

        夹角为锐角时,cosθ>0;夹角为钝角时,cosθ<0.

    """
    a_x, b_x, c_x = point_a[0], point_b[0], point_c[0]  # 点a、b、c的x坐标
    a_y, b_y, c_y = point_a[1], point_b[1], point_c[1]  # 点a、b、c的y坐标
    a_z, b_z, c_z = point_a[2], point_b[2], point_c[2]  # 点a、b、c的z坐标

    # 向量 m=(x1,y1,z1), n=(x2,y2,z2)
    x1, y1, z1 = (a_x - b_x), (a_y - b_y), (a_z - b_z)
    x2, y2, z2 = (c_x - b_x), (c_y - b_y), (c_z - b_z)

    # 两个向量的夹角,即角点b的夹角余弦值
    cos_b = (x1 * x2 + y1 * y2 + z1 * z2) / (
        math.sqrt(x1**2 + y1**2 + z1**2)
        * (math.sqrt(x2**2 + y2**2 + z2**2))
    )  # 角点b的夹角余弦值
    degree = math.degrees(math.acos(round(cos_b, 1)))  # 角点b的夹角值
    return degree


if __name__ == "__main__":
    a = [1, 2, 3]
    b = [2, 3, 4]
    c = [3, 4, 5]

    print(cal_angle(a, b, c))
    a_b = get_vector(a, b)
    b_c = get_vector(c, b)
    print(f"a_b: {a_b}")
    print(f"b_c: {b_c}")
    print(calculate_angle_degree(a_b, b_c))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过两个三维坐标计算欧拉角,你需要使用适当的数学公式。假设你有两个三维坐标分别为 `p1 = (x1, y1, z1)` 和 `p2 = (x2, y2, z2)`。以下是计算欧拉角的一种方法: 1. 首先,计算两个坐标的差值:`d = (x2 - x1, y2 - y1, z2 - z1)`。 2. 计算 yaw 角(绕垂直轴旋转角):`yaw = atan2(d[1], d[0])`。 3. 计算 pitch 角(绕横轴旋转角):`pitch = atan2(d[2], sqrt(d[0]**2 + d[1]**2))`。 4. 计算 roll 角(绕纵轴旋转角):`roll = atan2(sin(pitch)*d[0] - cos(pitch)*d[1], cos(pitch)*d[0] + sin(pitch)*d[1])`。 在这个方法中,我们使用了 `atan2` 函数来计算角值。请注意,结果的单位是弧。如果你需要将结果转换为数,可以使用 `math.degrees()` 函数来进行转换。 下面是一个示例代码,展示了如何计算两个三维坐标的欧拉角: ```python import math p1 = (1, 2, 3) p2 = (4, 5, 6) d = (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]) yaw = math.atan2(d[1], d[0]) pitch = math.atan2(d[2], math.sqrt(d[0]**2 + d[1]**2)) roll = math.atan2(math.sin(pitch)*d[0] - math.cos(pitch)*d[1], math.cos(pitch)*d[0] + math.sin(pitch)*d[1]) yaw_degrees = math.degrees(yaw) pitch_degrees = math.degrees(pitch) roll_degrees = math.degrees(roll) print("Yaw:", yaw_degrees) print("Pitch:", pitch_degrees) print("Roll:", roll_degrees) ``` 在这个示例中,我们计算了两个三维坐标的欧拉角,并将结果以数的形式打印出来。你可以将 `p1` 和 `p2` 替换为你自己的坐标点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值