计算一个点 (结构式) 围绕一条直线旋转angle角之后的空间坐标,Python实现
程序员文章站
2022-04-01 19:59:07
...
直接上代码
import math
#计算空间上两个点的距离。
#点在空间的坐标类似于p (x, y, z)
@staticmethod
def getDistanceBetweenTwoPoints(p1, p2):
return math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2 + (p1.z - p2.z) ** 2)
#空间中,一个结构式围绕一条直线line旋转angle角之后。求旋转之后的结构式上所有点的坐标
#已知直线上两个点为p1,p2。两个点确定一条直线。无所谓结构式上的点是否在此直线上。
#参考:https://www.cnblogs.com/leejxyz/p/5250935.html
#参考网页中错误较多,需要改正
#我不知道具体的原理是什么,反正结果是正确的。
@staticmethod
def structureRotateLineByAngle(listPoint, p1, p2, angle):
distance = MathTool.getDistanceBetweenTwoPoints(p1, p2)
#方向向量(u,v,w)需为单位向量!!!请仔细查看什么是单位向量,怎么计算单位向量中每个方向的值
#网页中的单位向量用的是sqrt(3) /3。这是不对的
#注意,如果p1和p2这两个点重叠,则无法计算单位向量
u = (p1.x - p2.x) /distance
v = (p1.y - p2.y) /distance
w = (p1.z - p2.z) /distance
SinA = math.sin(angle * math.pi / 180)
CosA = math.cos(angle * math.pi / 180)
uu = u * u
vv = v * v
ww = w * w
uv = u * v
uw = u * w
vw = v * w
t00 = uu + (vv + ww) * CosA
t10 = uv * (1 - CosA) + w * SinA
t20 = uw * (1 - CosA) - v * SinA
t01 = uv * (1 - CosA) - w * SinA
t11 = vv + (uu + ww) * CosA
t21 = vw * (1 - CosA) + u * SinA
t02 = uw * (1 - CosA) + v * SinA
t12 = vw * (1 - CosA) - u * SinA #网页中的t12被写成t21
t22 = ww + (uu + vv) * CosA
a0 = p2.x
b0 = p2.y
c0 = p2.z
t03 = (a0 * (vv + ww) - u * (b0 * v + c0 * w)) * (1 - CosA) + (b0 * w - c0 * v) * SinA
t13 = (b0 * (uu + ww) - v * (a0 * u + c0 * w)) * (1 - CosA) + (c0 * u - a0 * w) * SinA
t23 = (c0 * (uu + vv) - w * (a0 * u + b0 * v)) * (1 - CosA) + (a0 * v - b0 * u) * SinA
#新的坐标的list
newlistPoint = []
for p in listPoint:
newPoint = Point(t00 * p.x + t01 * p.y + t02 * p.z + t03,
t10 * p.x + t11 * p.y + t12 * p.z + t13,
t20 * p.x + t21 * p.y + t22 * p.z + t23)
newlistPoint.append(newPoint)
#返回旋转之后的坐标list
return newlistPoint