You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将平行于XY平面的两个圆旋转至垂直于p1-p0方向?

实现垂直于指定轴线的圆柱顶点生成

现有代码问题

当前代码生成的圆和圆柱始终平行于XY平面,无法适配任意方向的轴线(p1-p0)。需要修改代码,让圆所在平面垂直于p1-p0的方向。

现有生成平行XY平面圆的代码

import math

def circle(point, radius):
    circle_vertices = []
    [x0, y0, z0] = point
    for angle in range(0, 360, 10):
        angle_radius = math.radians(angle)
        x = x0 + radius * math.cos(angle_radius)
        y = y0 + radius * math.sin(angle_radius)
        circle_vertices.append([x, y, z0])
    return circle_vertices

现有生成平行XY平面圆柱的代码

def cylinder(point_0, point_1, radius):
    circle_vertices_0 = circle(point=point_0, radius=radius)
    circle_vertices_1 = circle(point=point_1, radius=radius)

    cylinder_vertices = circle_vertices_1 + circle_vertices_0

    return cylinder_vertices

修改方案:生成任意法线方向的圆

要让圆平面垂直于p1-p0方向,核心是基于轴线方向构建局部坐标系,将原XY平面的圆顶点变换到该局部坐标系中。

辅助向量运算函数

先实现基础的向量操作,用于构建局部坐标系:

def subtract(v1, v2):
    """向量减法:v1 - v2"""
    return [v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2]]

def normalize(v):
    """向量归一化"""
    length = math.sqrt(v[0]**2 + v[1]**2 + v[2]**2)
    if length < 1e-9:
        raise ValueError("零向量无法归一化")
    return [v[0]/length, v[1]/length, v[2]/length]

def cross(v1, v2):
    """向量叉乘"""
    return [
        v1[1]*v2[2] - v1[2]*v2[1],
        v1[2]*v2[0] - v1[0]*v2[2],
        v1[0]*v2[1] - v1[1]*v2[0]
    ]

生成带法线方向的圆

替换原circle函数,生成平面法线为指定方向的圆:

def oriented_circle(center, radius, normal):
    """生成平面法线为normal的圆顶点列表"""
    circle_vertices = []
    # 归一化法线向量
    n = normalize(normal)
    # 找到第一个垂直于法线的向量(x轴方向)
    # 如果法线不是z轴方向,用(0,0,1)叉乘;否则用(1,0,0)
    if abs(n[2]) < 0.999:
        u = normalize(cross(n, [0, 0, 1]))
    else:
        u = normalize(cross(n, [1, 0, 0]))
    # 找到第二个垂直于法线和u的向量(y轴方向)
    v = cross(n, u)
    
    # 生成圆顶点
    for angle_deg in range(0, 360, 10):
        angle_rad = math.radians(angle_deg)
        # 用u和v向量组合出圆上的点
        dx = radius * math.cos(angle_rad)
        dy = radius * math.sin(angle_rad)
        x = center[0] + dx*u[0] + dy*v[0]
        y = center[1] + dx*u[1] + dy*v[1]
        z = center[2] + dx*u[2] + dy*v[2]
        circle_vertices.append([x, y, z])
    return circle_vertices

修改圆柱生成函数

使用新的oriented_circle函数,让两个圆的平面垂直于p1-p0方向:

def cylinder(point_0, point_1, radius):
    # 计算轴线方向向量(作为圆平面的法线)
    axis_dir = subtract(point_1, point_0)
    # 生成两个垂直于轴线的圆
    circle_vertices_0 = oriented_circle(center=point_0, radius=radius, normal=axis_dir)
    circle_vertices_1 = oriented_circle(center=point_1, radius=radius, normal=axis_dir)
    
    cylinder_vertices = circle_vertices_1 + circle_vertices_0
    return cylinder_vertices

代码说明

  • oriented_circle函数通过法线向量构建局部坐标系(u, v, n),其中u和v是圆平面内的正交单位向量,n是法线方向。
  • 原XY平面的圆顶点(cosθ, sinθ, 0)被转换为center + radius*(cosθ*u + sinθ*v),从而保证圆平面垂直于法线方向。
  • 圆柱的轴线方向就是两个圆心的连线,将其作为法线传入oriented_circle,即可让两个圆平面垂直于轴线。

内容的提问来源于stack exchange,提问作者XH-a

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:31:08