如何在3D空间任意两点构成的线段上生成正弦函数形变曲线
3D空间任意线段的正弦/自定义函数形变实现方案
核心实现思路
3D空间下的线段形变本质是先将线段转换到自身的局部正交坐标系,在垂直于线段方向的平面上叠加自定义函数形变后,再转换回世界坐标系即可适配任意位置、任意朝向的3D线段。
分步实现步骤
- 基础参数计算:给定线段起点
P0、终点P1,计算方向向量dir = P1 - P0,线段总长度L = np.linalg.norm(dir),单位方向向量u_dir = dir / L - 构建局部正交坐标系:生成两个与
u_dir正交的单位向量v_dir、w_dir,作为形变的偏移方向:- 取临时向量,若
u_dir与(1,0,0)的点积绝对值小于0.9则临时向量取(1,0,0),否则取(0,1,0) - 计算
v_dir = np.cross(temp_vec, u_dir)后做归一化 - 计算
w_dir = np.cross(u_dir, v_dir)自动得到第二个正交向量
- 取临时向量,若
- 生成形变点集:
- 取步进参数
t,取值范围[0, 1],步进密度可根据显示精度需求调整 - 计算线段上的基准点
base_pt = P0 + t * L * u_dir - 计算形变偏移量:正弦形变下偏移为
offset = A * np.sin(2 * np.pi * f * t) * v_dir,其中A为振幅、f为沿线段长度的正弦波数量,需要替换为其他自定义函数时直接修改该公式即可 - 最终形变点为
base_pt + offset,所有点拼接即为形变后的曲线
- 取步进参数
参考代码实现(Python + Numpy)
import numpy as np def deform_3d_segment(P0, P1, amp=0.5, freq=3, step=0.01): # 计算基础参数 dir_vec = P1 - P0 L = np.linalg.norm(dir_vec) u_dir = dir_vec / L # 构建正交坐标系 if abs(np.dot(u_dir, np.array([1,0,0]))) < 0.9: temp_vec = np.array([1,0,0]) else: temp_vec = np.array([0,1,0]) v_dir = np.cross(temp_vec, u_dir) v_dir = v_dir / np.linalg.norm(v_dir) # 生成点集 t_list = np.arange(0, 1+step, step) pts = [] for t in t_list: base_pt = P0 + t * L * u_dir # 可替换为任意自定义形变函数 offset = amp * np.sin(2 * np.pi * freq * t) * v_dir pts.append(base_pt + offset) return np.array(pts)
扩展调整说明
- 若需要在垂直于线段的两个方向同时叠加形变,可分别计算
v_dir和w_dir方向的偏移量叠加即可 - 要调整形变的起始位置、相位,可修改sin函数的入参,比如添加相位参数
phase调整波形起始位置 - 步进参数
step越小,生成的曲线越平滑,可根据性能需求灵活调整
内容的提问来源于stack exchange,提问作者Верстак
相关产品推荐
相关产品推荐

