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

基于已知距离与角度的曲线上单点平移及Python函数优化

坐标点沿指定方向平移的优化实现

问题背景

需要将曲线上的目标点(x0,y0)沿**90°方向(曲线法向)**平移指定单位到(x1,y1),初始直接修改坐标的代码无法满足方向敏感性需求,现有基于向量旋转的函数存在逻辑冗余,需要优化。

初始失败代码

直接对坐标值做加法,仅能实现沿坐标轴方向平移,无法匹配90°法向平移的需求:

fig = plt.figure()
from mpl_toolkits.mplot3d import Axes3D
ax = fig.add_subplot(111)

c = [55,  53, 54]
d = [29,  27,  27]

# 错误:直接给x/y加3,并非沿90°方向平移
c = [55,  53 + 3, 54]
dd = [29,  27 + 3,  27 ]

ax.plot(c,d,'-o', c='g')
ax.plot(c,dd,'-o', c='b')

现有待优化代码

以下是尝试用向量旋转实现方向敏感平移的代码,但存在逻辑冗余和计算错误,需要调整:

fig = plt.figure()
from mpl_toolkits.mplot3d import Axes3D
ax = fig.add_subplot(111)
    

a = [0.22520001, 0.22140153, 0.21732369, 0.21258711, 0.20764232, 0.20515779,
0.20449048, 0.20467589, 0.20534733]
b = [0.21270538 ,0.21026637, 0.20749939, 0.20383899, 0.19925433, 0.19559762,
0.19440357, 0.19375025, 0.19344115]


dev = [0.0009969 , 0.00143304, 0.00174457, 0.00193148, 0.00199379, 0.00186918,
0.00149534, 0.00087228, 0.        ]

import math

def rotate_vector(x0, y0, angle, dev):
    magnitude = math.sqrt(x0**2 + y0**2)
    xhat = x0/magnitude
    yhat = y0/magnitude
    x_rot = -yhat * math.sin(angle) + xhat * math.cos(angle)
    y_rot = yhat * math.cos(angle) + xhat * math.sin(angle)
    x_rot = x_rot * dev
    y_rot = y_rot * dev

    anglee = 90 # Obviously different if 0 or 45, etc...

    x_rot = (x_rot * math.cos(np.radians(anglee))) - (y_rot * math.sin(np.radians(anglee)))
    y_rot = (x_rot * math.sin(np.radians(anglee))) + (y_rot * math.cos(np.radians(anglee))) 

    x_final = x_rot + x0
    y_final = y_rot + y0
    return x_final, y_final

优化后的方向敏感平移实现

核心思路:沿曲线**法向(与切线垂直的90°方向)**平移,先计算目标点的切线方向,再推导法向向量,最后完成指定距离的平移。

优化后的函数

import math
import numpy as np
import matplotlib.pyplot as plt

def translate_point_along_normal(x_coords, y_coords, point_idx, distance):
    # 处理首尾点的边界情况,获取切线方向
    if point_idx == 0:
        dx = x_coords[1] - x_coords[0]
        dy = y_coords[1] - y_coords[0]
    elif point_idx == len(x_coords)-1:
        dx = x_coords[-1] - x_coords[-2]
        dy = y_coords[-1] - y_coords[-2]
    else:
        # 中间点用前后两点的平均斜率作为切线方向
        dx = x_coords[point_idx+1] - x_coords[point_idx-1]
        dy = y_coords[point_idx+1] - y_coords[point_idx-1]
    
    # 计算切线单位向量
    tangent_mag = math.hypot(dx, dy)
    tangent_x = dx / tangent_mag
    tangent_y = dy / tangent_mag
    
    # 计算90°法向单位向量(逆时针方向,如需顺时针则取负)
    normal_x = -tangent_y
    normal_y = tangent_x
    
    # 沿法向平移指定距离
    new_x = x_coords[point_idx] + normal_x * distance
    new_y = y_coords[point_idx] + normal_y * distance
    
    return new_x, new_y

# 测试示例
a = [0.22520001, 0.22140153, 0.21732369, 0.21258711, 0.20764232, 0.20515779,
0.20449048, 0.20467589, 0.20534733]
b = [0.21270538 ,0.21026637, 0.20749939, 0.20383899, 0.19925433, 0.19559762,
0.19440357, 0.19375025, 0.19344115]

# 平移第2个点(索引1),距离0.003
new_x, new_y = translate_point_along_normal(a, b, 1, 0.003)

# 生成平移后的曲线坐标
a_shifted = a.copy()
b_shifted = b.copy()
a_shifted[1] = new_x
b_shifted[1] = new_y

# 绘图展示
fig, ax = plt.subplots()
ax.plot(a, b, '-o', c='g', label='原曲线')
ax.plot(a_shifted, b_shifted, '-o', c='b', label='平移后曲线')
ax.legend()
plt.show()

优化说明

  • 边界处理:针对曲线首尾点,用相邻点计算切线方向;中间点用前后两点的平均斜率,保证所有点都能得到准确的法向
  • 逻辑简化:直接从切线推导90°法向向量,避免原代码中冗余的多层旋转计算
  • 可配置性:支持指定任意平移距离,可通过反转法向向量符号切换顺时针/逆时针90°方向

内容的提问来源于stack exchange,提问作者Acqueux

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:01:00