【问题标题】:Java: Intersection of two ellipse segments transformed into 3d spaceJava:两个椭圆段的交点转换为 3d 空间
【发布时间】:2019-02-06 11:19:18
【问题描述】:

我有线段和椭圆(不是平面和椭圆体)转换为3d 空间,需要计算两个给定线段是否相交以及在哪里。

我正在使用 Java,但还没有找到可以解决我的问题的库,也没有找到一些可以用于我自己的实现的算法。

【问题讨论】:

  • 我认为(尽管不是 100% 确定)这相当于检查生成的对象在三个坐标平面中的每一个上的 2D 投影是否相交。然而,这将排除使用依赖于使用椭圆本身的公式求解的解决方案,因为 2D 投影本身不会形成椭圆。
  • 如果您与我们分享一些代码会很酷。比如你到现在为止有什么,你的输入数据怎么样等等。

标签: java 3d line intersection ellipse


【解决方案1】:

对于线-线相交测试有几种解决方法。经典的方式是使用线性代数(即求解线性矩阵系统),但从软件开发的角度来看,我更喜欢几何代数方式,采用 Plucker Coordinates 的形式,它只需要实现向量代数运算(即, cross-product 和 dot-product) 比求解线性系统的矩阵运算更简单。

为了比较,我将两者都显示,然后您决定:

线性代数法

给定线段 P 由点 P1 和 P2 限制,线段 Q 由点 Q1 和 Q2 限制。

线的参数形式由下式给出:

P(t) = P1 + t (P2 - P1)

Q(t) = Q1 + t (Q2 - Q1)

其中 t 是区间 [0 1] 中的实数。

如果两条线相交,则以下等式成立:

P(t0) = Q(t1)

假设存在两个未知数 t0 和 t1。展开上面的方程我们得到:

t0 (P2 - P1) - t1 (Q2 - Q1) = Q1 - P1

我们可以通过用矩阵代数表达上述方程来求解t0和t1:

A x = B

其中 A 是一个 3x2 矩阵,第一列是向量 (P2 - P1) 的坐标,第二列是向量 (Q2 - Q1) 的坐标; x 是未知数 t0 和 t1 的 2x1 列向量,B 是具有向量坐标 (Q1 - P1) 的 3x1 列向量。

系统可以通过计算矩阵 A 的伪逆来求解,记为 A^+:

A^+ = (A^T A)^-1 A^T

见: https://en.m.wikipedia.org/wiki/Generalized_inverse

幸运的是,Java 中的任何矩阵包都应该能够非常轻松地计算上述计算,也许也非常有效。

如果将 A 与其伪逆 A^+ 相乘等于单位矩阵 I,即 (A A^+) == I,则存在唯一答案(交集),您可以通过以下计算得到它产品:

x = A^+ B

当然,如果您一开始就无法计算伪逆,例如,因为 (A^T A) 是奇异的(即行列式为零),则不存在交集。

由于我们正在处理线段,因此交点在点 P(x0) 或 Q(x1) 上,当且仅当 x0 和 x1 都在区间 [0 1] 内。

其他解决方法

为了避免处理矩阵代数,我们可以尝试使用向量代数和替换方法来求解系统:

t0 (P2 - P1) - t1 (Q2 - Q1) = Q1 - P1

t0 = a + t1 b

t1 = C • (Q1 - (1 - a) P1 - a P2) / |C|^2

地点:

a = (P2 - P1) • (Q1 - P1) / |P2 - P1|^2

b = (P2 - P1) • (Q2 - Q1) / |P2 - P1|^2

C = b (P2 - P1) - (Q2 - Q1)

我还不能提供上述结果的几何直觉。

Plucker坐标方式

给定线段 P 由点 P1 和 P2 限制,线段 Q 由点 Q1 和 Q2 限制。

线 P 的 Plucker 坐标由一对 3d 向量 (Pd, Pm) 给出:

Pd = P2 - P1

Pm = P1 x P2

其中 Pm 是 P1 和 P2 的叉积。 Q线的Plucker坐标(Qd,Qm)可以用同样的方法计算出来。

线 P 和 Q 只有在它们共面时才能相交。 Thr线P和Q是共线iif:

Pd • Qm + Qd • Pm = 0

其中 (•) 是点积。由于机器的精度有限,因此稳健的测试不应该检查零,而是检查少量。如果 Pd x Qd = 0,那么线是平行的(这里 0 是零向量)。对于 (Pd x Qd) 的平方长度很小的情况,再次进行稳健的测试。

如果线不平行,则它们是共面的,它们的交点(在 Plucker 的行话中称为“相遇”)将是点:

x = ((Pm • N) Qd - (Qm • N) Pd - (Pm • Qd) N) / (Pd x Qd) • N

其中 N 是任何坐标轴矢量(即 (1,0,0) 或 (0,1,0) 或 (0,0,1)),因此 (Pd x Qd) • N 是非零。

如果 P 和 Q 都不通过原点,那么它们的 Plucker 坐标 Pm 和 Qm 分别不为零,下面的 sinpler 公式将起作用

x = Pm x Qm / Pd • Qm

有关 Plucker 坐标的介绍,请参阅:

https://en.m.wikipedia.org/wiki/Plücker_coordinates

http://www.realtimerendering.com/resources/RTNews/html/rtnv11n1.html#art3

对于一般的交集公式,请参见“推论 6”:

http://web.cs.iastate.edu/~cs577/handouts/plucker-coordinates.pdf

将椭圆前后转换为圆

我们总是可以把一个椭圆变成一个圆。椭圆有两个“半径”,称为半轴,您可以在脑海中将其可视化为两个正交向量,一个大的称为主半轴,一个小的称为次半轴。您可以对两个半轴向量应用非均匀缩放变换,以使它们大小相等,从而得到一个圆。

我们通过它的中心 O 定义一个椭圆“E”,它是一个 3d 点和它的两个半轴 A1 和 A2,它们也是 3d 向量。椭圆平面的法线向量 N 可以通过其半轴 N = A1 x A2 的叉积计算,然后将其归一化为单位长度。

现在假设有一个线性函数 M 可用于将椭圆 E 转换(缩放)为半径等于次半轴的圆 C,方法是将其应用于椭圆的半轴 A1 和A2 到椭圆的中心 O。

注意椭圆的中心O和椭圆的法向量N并没有被M改变。所以M(N) = N和M(O) = O。这意味着圆在同一个平面上并且具有相同的位置C 比椭圆。线性函数M有一个对应的反函数M^-1,所以我们可以将圆的向量变换回原来的椭圆E。

当然,我们也可以使用函数 M 转换线 P 和 Q 的端点,将它们发送到“圆形空间”,我们可以使用 M^-1 将它们发送回“椭圆空间”。

使用 M,我们可以计算线 P 和 Q 与圆空间中的椭圆 E 的交点。所以现在我们可以关注线圆交点了。

线平面交点

给定一个具有法向量 N 和距离 D 的平面,使得:

N • x + D = 0

对于平面中的每个点 x。那么与 Plucker 坐标 (Pd, Pm) 的线 P 的交点由下式给出:

x = (N x Pm - D Pd) / N • Pd

仅当线 P 不在平面内时才有效,即:

(N • P1 + D) != 0 和 (N • P2 + D) != 0

对于我们的椭圆 E,我们有:

N = (A1 x A2)/|A1 x A2|

D = -N • O

线-圆和点-圆的交点

现在有了 x,圆点检查很容易:

|O - x|

只有当 x 在圆边界内时,等式才成立。

如果线 P 在圆的平面内,那么下面的简单检查会给你答案:

https://stackoverflow.com/a/1079478/9147444

如何计算线性函数M

计算 M 的简单方法如下。使用椭圆的法线向量 N 和半轴 A1 和 A2 创建一个 3x3 矩阵 U。这样 U 就以向量 A1、A2 和 N 作为列。

然后缩放主要半轴 A1,使其与次要半轴 A2 具有相同的长度。然后创建矩阵 V 以使 V 具有新的向量 A1 和 A2 以及 N 作为列。

然后我们定义线性矩阵系统:

R U = V

其中 R 是一个 3x3(非均匀)缩放旋转矩阵。

我们可以通过将等式两边乘以 U 的倒数 U^-1 来求解 R

R U U^-1 = V U^-1

由于 U U^-1 是我们得到的单位矩阵:

R = V U^+

我们使用 R 定义仿射变换

M(x) = R (x - O) + O

我们可以使用 M 将点转换为圆空间,例如 O、P1、P2、Q1 和 Q2。但是如果我们需要对A1、A2、N、Pd和Qd等向量进行变换。我们需要使用更简单的 M:

M(x) = R x

由于 A1、A2 和 N 是 R 的特征向量,因此 R 不是奇异的并且具有逆。我们将逆 M 定义为:

M^-1(x) = R^-1 (x - O) + O

对于向量:

M^-1(x) = R^-1 x

更新:椭圆-椭圆相交

两个相交的非共面 3d 椭圆的交点位于由它们的平面相交形成的线上。因此,您首先找到由包含椭圆的平面相交形成的线(如果平面不相交,即它们平行,则椭圆都不相交)。

相交线属于两个平面,因此它垂直于两个法线。方向向量V是平面法线的叉积:

V = N1 × N2

要完全确定直线,我们还需要在直线上找到一个点。我们可以解决平面的线性方程。给定 2x3 矩阵 N = [N1^T N2^T],法线 N1 和 N2 作为行,以及 2x1 列向量 b = [N1 • C1, N2 • C2],其中 C1 和 C2 是椭圆的中心,我们可以形成线性矩阵系统:

N X = b

其中 X 是满足两个平面方程的某个点。系统是欠定的,因为满足系统的直线上有无数个点。我们仍然可以通过使用矩阵 N 的伪逆来找到更接近原点的特定解,记为 N^+。

X = N^+ b

直线方程为

L(t) = X + t V

对于一些标量 t。

然后您可以应用前面描述的方法来测试线-椭圆相交,即将椭圆缩放为圆形并与共面线相交。如果两个椭圆在同一点与直线相交,则它们相交。

现在,椭圆实际上位于同一平面上的情况更加复杂。您可以在 Eberly 博士的优秀著作《几何工具》(也可在线获取)中查看该方法:

https://www.geometrictools.com/Documentation/IntersectionOfEllipses.pdf

您还可以查看开源的 C++ 源代码:

https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrEllipse2Ellipse2.h

【讨论】:

  • 首先:非常感谢您的详细描述。我实现了 line-line-intersection 和 ellipse-line-intersection ,一切都很顺利。但是,我不知道如何计算 ellipse-ellipse-intersection (带有具体的交点)。如果你也能帮助我,那就太好了。此外,我想问你是否知道一个简单的检查点是否位于椭圆的圆周上。
  • 定义平面时,我会用法向量和原点来定义它。您通过法线向量和距离定义。这个距离是多少,我该如何计算? (也用于测试目的)
  • 这是平面的笛卡尔方程。由四个数 A、B、C 和 D 定义。方程为 A x + B y + C z + D = 0。其中 (A,B,C) 是平面的单位法向量,D 是距平面的最短距离飞机到原点。它可以写成 N • x + D = 0。如果平面通过原点,则 D = 0。在你的情况下,平面由椭圆 N 的法线和椭圆 C 的中心定义。距离 D 只是D = -N • C。因为 D 是 C 沿法线方向的投影。另见:sites.math.washington.edu/~king/coursedir/m445w04/notes/vector/…
猜你喜欢
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 2021-11-19
  • 2016-07-21
  • 1970-01-01
  • 2018-03-20
相关资源
最近更新 更多