基于Python求解三角形中固定相对位置的未知点坐标
解决方案:利用刚体变换(平移+旋转)计算自定义点新坐标
不用圆交点法,直接通过刚体变换计算是更高效可靠的方案——因为三角形形状大小不变,本质是将初始参考点变换到新位置时,自定义点跟着做相同的平移和旋转(或镜像)。
实现步骤
- 计算初始参考点间的向量,以及自定义点相对于第一个参考点的向量
- 计算新参考点间的向量,推导旋转矩阵(将初始参考向量旋转到新参考向量的方向)
- 用旋转矩阵变换自定义点的相对向量,再平移到新参考点的坐标系中
- 可选:处理镜像翻转的情况(对应圆交点的另一个解)
Python 代码实现
import math def calculate_new_custom_point(R1_initial, R2_initial, C_initial, R1_new, R2_new): # 解析坐标:每个点是(x, y)元组 xr1, yr1 = R1_initial xr2, yr2 = R2_initial xc, yc = C_initial xr1_new, yr1_new = R1_new xr2_new, yr2_new = R2_new # 计算初始向量:R1到R2,R1到C v_initial_x = xr2 - xr1 v_initial_y = yr2 - yr1 w_initial_x = xc - xr1 w_initial_y = yc - yr1 # 计算新参考向量:R1_new到R2_new v_new_x = xr2_new - xr1_new v_new_y = yr2_new - yr1_new # 计算向量长度(因为三角形大小不变,理论上len_v_initial == len_v_new,这里做校验) len_v_initial = math.hypot(v_initial_x, v_initial_y) len_v_new = math.hypot(v_new_x, v_new_y) if abs(len_v_initial - len_v_new) > 1e-6: raise ValueError("新参考点间距与初始不符,无法保持三角形大小不变") # 计算旋转角度的余弦和正弦值 dot_product = v_initial_x * v_new_x + v_initial_y * v_new_y cross_product = v_initial_x * v_new_y - v_initial_y * v_new_x cos_theta = dot_product / (len_v_initial ** 2) sin_theta = cross_product / (len_v_initial ** 2) # 旋转自定义点的相对向量,再平移到新参考点(同向三角形) c_rotated_x = cos_theta * w_initial_x - sin_theta * w_initial_y c_rotated_y = sin_theta * w_initial_x + cos_theta * w_initial_y C_new = (xr1_new + c_rotated_x, yr1_new + c_rotated_y) # 镜像翻转的情况(反向三角形,对应圆交点的另一个解) c_mirrored_x = cos_theta * w_initial_x + sin_theta * w_initial_y c_mirrored_y = -sin_theta * w_initial_x + cos_theta * w_initial_y C_new_mirrored = (xr1_new + c_mirrored_x, yr1_new + c_mirrored_y) return C_new, C_new_mirrored
代码说明
- 输入参数:每个点都是(x, y)的元组或列表
- 返回值:两个可能的自定义点坐标——一个是和初始三角形同向的解,另一个是镜像翻转的解,可根据实际场景选择
- 校验步骤:确保新参考点的间距和初始一致,避免不符合“大小不变”的输入
- 计算效率:全程都是代数运算,没有迭代或图形渲染,速度极快,内存占用可忽略
示例用法
# 初始点 R1 = (0, 0) R2 = (2, 0) C = (1, 1) # 新参考点(R1移到(3,3),R2移到(5,3),相当于平移) R1_new = (3, 3) R2_new = (5, 3) C_normal, C_mirrored = calculate_new_custom_point(R1, R2, C, R1_new, R2_new) print("同向解:", C_normal) # 输出 (4,4),符合预期 print("镜像解:", C_mirrored) # 输出 (4,2)
内容的提问来源于stack exchange,提问作者Liam
相关产品推荐
相关产品推荐

