在空间中给出三个点(3D)找到弧/圆方程

时间:2013-12-01 16:20:26

标签: python numpy geometry

给出空间中的3个点(3D):A =(x1,y1,z1),B =(x2,y2,z2)C =(x3,y3,z3);那么如何找到通过这三个点的圆(圆弧)的中心和半径,即找到圆方程?这里使用Python和Numpy是我的初始代码

import numpy as np
A = np.array([x1, y1, z1])
B = np.array([x2, y2, z2])
C = np.array([x3, y3, z3])

#Find vectors connecting the three points and the length of each vector
AB = B - A 
BC = C - B 
AC = C - A 

# Triangle Lengths
a = np.linalg.norm(AB)
b = np.linalg.norm(BC)
c = np.linalg.norm(AC)

根据Circumradius定义,可以使用以下方法找到半径:

R = (a * b * c) / np.sqrt(2.0 * a**2 * b**2 +
                          2.0 * b**2 * c**2 +
                          2.0 * c**2 * a**2 -
                          a**4 - b**4 - c**4)

然而,我在找到中心的笛卡尔坐标时遇到了问题。一种可能的解决方案是使用三角形点的“重心坐标”来找到外心(Circumcenter)的三线坐标。

首先(using this source)我们找到了外心的圆心坐标:

#barcyntric coordinates of center
b1 = a**2 * (b**2 + c**2 - a**2)
b2 = b**2 * (c**2 + a**2 - b**2)
b3 = c**2 * (a**2 + b**2 - c**2)

然后中心(P)的笛卡尔坐标为:

Px = (b1 * A[0]) + (b2 * B[0]) + (b3 * C[0])
Py = (b1 * A[1]) + (b2 * B[1]) + (b3 * C[1])
Pz = (b1 * A[2]) + (b2 * B[2]) + (b3 * C[2])   

但是,上面的barcyntric坐标值似乎不正确。当用已知值的示例求解时,半径是正确的,但是中心的坐标不是。

示例:对于以下三点:

A = np.array([2.0, 1.5, 0.0])
B = np.array([6.0, 4.5, 0.0])
C = np.array([11.75, 6.25, 0.0]) 

半径和中心坐标为:

R = 15.899002930062595
P = [13.4207317073, -9.56097560967, 0]

有关如何找到中心坐标的任何想法?

2 个答案:

答案 0 :(得分:10)

您的代码存在两个问题。

第一个是命名约定。对于您要使用的所有公式,长度为a的边必须是与A点相对的边,bB以及{{ 1}}和c。你可以通过计算它们来解决这个问题:

C

第二个与你的音符中的​​音符有关的外心坐标的重心坐标:不一定是同质的。也就是说,它们不需要以任何方式进行标准化,并且用于从重心坐标计算笛卡尔坐标的公式仅在它们加起来时才有效。

幸运的是,您只需将得到的笛卡尔坐标除以a = np.linalg.norm(C - B) b = np.linalg.norm(C - A) c = np.linalg.norm(B - A) 即可得到您所追求的结果。简化您的代码以提高效率,我得到您期望的结果:

b1 + b2 + b3

答案 1 :(得分:1)

作为对原始问题的扩展:现在假设我们具有从如上定义的点A(远离点B)延伸的已知长度的弧(例如,1个单位)。如何找到终点(N)的3D坐标?新点N位于通过A,B和B点的同一圆上。 C.

这可以通过首先找到两个矢量PA&之间的角度来解决。 PN:

# L = Arc Length 
theta = L / R

现在我们需要做的就是按照正确的方向旋转矢量PA(半径)。为此,我们需要3D旋转矩阵。为此,我们使用Euler–Rodrigues formula

def rotation_matrix_3d(axis, theta):
    axis = axis / np.linalg.norm(axis)
    a = np.cos(theta / 2.0)
    b, c, d = axis * np.sin(theta / 2.0)   
    rot = np.array([[a*a+b*b-c*c-d*d,     2*(b*c-a*d),     2*(b*d+a*c)],
                    [    2*(b*c+a*d), a*a+c*c-b*b-d*d,     2*(c*d-a*b)],
                    [    2*(b*d-a*c),     2*(c*d+a*b), a*a+d*d-b*b-c*c]])
    return rot

接下来,我们需要找到旋转轴来旋转PA。这可以通过找到垂直于通过A,B和B的圆的平面的轴来实现。 C.然后可以从圆的中心找到点N的坐标。

PA = P - A
PB = P - B
xx = np.cross(PB, PA)
r3d = rotation_matrix_3d(xx, theta)
PN = np.dot(r3d, PA)
N = P - PN

作为一个例子,我们想要找到距离点A 3度的点N的坐标,坐标将是

N = (1.43676498,  0.8871264,   0.) 

哪个是对的! (使用CAD程序手动验证)