使用 python 找到三角形中的第三个点

问题描述 投票:0回答:1

我正在尝试创建一个 python 函数,以在给定两个可以更改的参考点的情况下找到预定位置的坐标。

一开始我在网格上有三个点参考点1(Xr1,Yr1),参考点2(Xr2,Yr2)和自定义点(Xc ,Yc).最初所有三个点都是已知的,但对于后续运动,可以测量参考点 1 和参考点 2,但自定义点是未知的。在这 3 个点之间绘制的三角形的形状和大小不会改变。

鉴于此,python中有没有好的方法取初始3个点的坐标和新的2个参考点的坐标,并计算自定义点新位置的坐标。 (绿色值已知,红色值未知)

我已经尝试使用参考点和自定义点之间的距离作为半径在新点周围绘制圆圈并找到截距。然而,这种方法很慢,而且内存占用很大,因为我使用的是非常大的坐标距离,而且它的实现相当不可靠。

在此方面的任何帮助将不胜感激。

python geometry coordinates trigonometry triangulation
1个回答
0
投票

这里有一个可能的解决方案,使用一个围绕原点 (0,0) 旋转点的函数:

策略是将坐标转置到一个已知点周围的参考系。然后应用另一个已知点的相对旋转来计算未知的第三点。

如果我们在移动A和B之后命名三角形的3个点A,B和C,C是未知数,过程如下:

  • 将B和C转换成以A为原点的相对坐标==> B0和C0
  • 计算 B0 与原点的夹角。那是 AB 线段的旧角度(可以使用 math.atan2 轻松获得)
  • 将newB点转换为以newA为原点的相对坐标==> newB0
  • 从原点计算 newB0 的角度
  • B0 和 newB0 的角度之间的增量将应用于原始 C0 点以产生 newC0(使用点旋转功能)
  • 通过从 newA 翻译将 newC0 转换为 newC

...

import math
def rotatePoint(x,y,angle):
    s,c = math.sin(angle), math.cos(angle)
    return (x*c-y*s, x*s+y*c)

def getNewC(A,B,C,newA,newB):
    Ax,Ay = A
    Bx,By = B
    Cx,Cy = C
    
    B0x,B0y    = Bx-Ax, By-Ay
    oldAngleAB = math.atan2(B0y,B0x)

    newAx,newAy   = newA
    newBx,newBy   = newB
    newB0x,newB0y = newBx-newAx, newBy-newAy
    newAngleAB    = math.atan2(newB0y,newB0x)

    C0x,C0y       = Cx-Ax, Cy-Ay
    newC0x,newC0y = rotatePoint(C0x,C0y,newAngleAB - oldAngleAB)
    newCx,newCy   = newAx+newC0x, newAy+newC0y
    
    return newCx,newCy

输出:(用海龟来说明)

import turtle
t = turtle.Turtle()

A = (10,10)
B = (60,10)
C = (30,120)
    
t.penup()
t.goto(*A)
t.pendown()
t.goto(*B)
t.goto(*C)
t.goto(*A)

newA = (-10,-10)
newB = (-10,-60)
newC = getNewC(A,B,C,newA,newB)

t.pen(pencolor="red")
t.penup()
t.goto(*newA)
t.pendown()
t.goto(*newB)
t.goto(*newC)
t.goto(*newA)
t.penup()

newA = (-40,40)
newB = (-70,80)
newC = getNewC(A,B,C,newA,newB)

t.pen(pencolor="blue")
t.penup()
t.goto(*newA)
t.pendown()
t.goto(*newB)
t.goto(*newC)
t.goto(*newA)
t.penup()

请注意,这不会执行任何缩放。它假设两个基点之间的距离在移动后保持不变。如果最终确实需要缩放,可以在从 newC0 到 newC 的转换的末尾添加它:

scale         = ((newB0x**2+newB0y**2)/(B0x**2+B0y**2))**0.5
newCx,newCy   = newAx+newC0x*scale, newAy+newC0y*scale

输出:

newA = (100,100)
newB = (110,210)
newC = getNewC(A,B,C,newA,newB)

t.pen(pencolor="purple")
t.penup()
t.goto(*newA)
t.pendown()
t.goto(*newB)
t.goto(*newC)
t.goto(*newA)
t.penup()
© www.soinside.com 2019 - 2024. All rights reserved.