通过边长和它们之间的角度确定多边形顶点坐标的算法

问题描述

解决确定问题的一般算法是什么 任意多边形顶点的坐标,通过边长和它们之间的角度。 例如,我们有一个边长数组 [10 10 10 10]一个角度数组 [90 90 90 90], 我们需要得到一个顶点坐标数组 [[0 0] [10 0] [10 10] [0 10]]。 检查数据:

  1. l=[10 10 10] a=[60 60 60] => [[0 0] [10 0] [5 8.66]]
  2. l=[20 14.14 10 10] a=[45 135 90 90] => [[0 0] [10 0] [20 10] [0 10]

解位于坐标网格上的哪个位置无关紧要。旋转方向(顺时针或逆时针)也无关紧要。主要的是生成的坐标集对应于原始条件。可能集合中的任何解决方案都值得关注。

澄清。假设多边形的第一条边位于 X 轴上,顶点的坐标为 [0 0] [L 0],其中 L 是边的长度。顺时针旁路。

解决方法

我们称“Ang”为边相对于 X 轴的角度。未给出该值,但可以通过将该边之前的所有边之间的角度相加来计算。

因此,对于边 1,我们有“Ang= 0”(假设)。对于边 2,我们知道边 1 的内角(比如“a2”)。所以对于这条边,我们有“Ang= 0 + a2”。
如果边 3 的内角是“a3”,那么我们有“Ang= 0 + a2 + a3”。其余边依此类推。

你说边之间的角度是顺时针给定的。因为三角函数使用顺时针系统,所以我们必须改变中间角度的符号。

要计算边的 X、Y 分量,我们将使用三角函数“cos(a)”和“sin(a)”,其中“a”是逆时针测量的角度。
这些组件是

x = L * cos(a)
y = L * sin(a)

其中 L 是边的长度。

坐标是添加这些组件的上一条边的坐标。

综合起来,我们有伪代码:

//First vertex
x(0) = 0
y(0) = 0

Ang = 0;

for i=1 to numOfVertices {
    Ang = Ang - a(i)
    x(i) = x(i-1) + L(i) * cos(Ang)
    y(i) = y(i-1) + L(i) * sin(Ang)
}

注意a(i)。这是与前一条边的角度。这意味着角度数组必须以“0”开头,这对应于第一条边相对于 X 轴的角度。
另外,请注意在三角函数中使用度数或弧度。

,

可能是这样的

import numpy as np
import matplotlib.pyplot as plt

def get_vertices(a,l):
    n = l.size
    p = np.empty((n+1,2),dtype=float)
    p[0,:] = np.array([0,0])
    p[n-1,0])
    p[1,:] = np.array([l[0],0])
    angle = 0
    for i in range(1,n-1):
        angle = angle + np.pi - a[i]
        v_edge = l[i]*np.array([np.cos(angle),np.sin(angle)])
        p[i+1,:] = p[i,:] + v_edge
    # correcting for the input data,the lase edge and the first and last angles
    l[n-1] = np.linalg.norm(p[n-1,:])
    a[0] = np.arccos(p[n-1,0]/l[n-1])  
    a[n-1] =  angle - a[0] 
    return p

a = np.array([0,np.pi/2,75*np.pi/180,np.pi/2])
l = np.array([1,1,np.sqrt(6)/2,np.sqrt(2)/2])

#a = np.array([0,0])
#l = np.array([1,0])
  
x,v = get_vertices(a,l)

fig,axs = plt.subplots(1)
axs.plot(x[:,0],x[:,1],'b')
for p in x:
  axs.plot(p[0],p[1],'ro')
axs.set_aspect('equal')
plt.grid()
plt.show()

一个评论:你要给算法的数据包含三个冗余。基本上,对于 n 个顶点的多边形,如果您有 n 个角度和 n 个边的数据,那么有 3 个方程,一个用于边,两个用于该边与其相邻边的角度。所以独立的输入参数应该更像是n-1条边和n-2个角。

如有必要,我让算法更正了您的角度和边缘数据。