- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将线段和椭圆段(非平面和椭圆体)转换为3d空间,并且需要计算两个给定的段是否相交以及在何处相交。
我正在使用Java,但是还没有找到可以解决我的问题的库,也没有遇到可以用于自己的实现的算法。
最佳答案
对于线-线相交测试,有几种解决方法。经典方式是使用线性代数(即求解线性矩阵系统),但是从软件开发的角度来看,我更喜欢采用Plucker坐标形式的Geometric-Algebra方式,该方式仅需要实现矢量代数运算(即,叉积和点积),比矩阵运算更容易编码,以解决线性系统问题。
为了进行比较,我将同时展示两者,然后您决定:
线性代数方式
给定线段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:
x = B
其中,A是一个3x2矩阵,第一列的向量(P2-P1)坐标,第二列的向量(Q2-Q1)坐标; x是未知数t0和t1的2x1列向量,B是3x1列向量,坐标为向量(Q1-P1)。
经典地,该系统可以通过计算矩阵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)
我还不能提供上述结果的几何直觉。
采摘坐标方式
给定线段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(一个3d点)以及两个半轴A1和A2(它们也是3d向量)定义一个椭圆“ E”。可以通过椭圆半平面的叉积N = A1 x A2求出椭圆平面的法向矢量N,然后将其规格化为单位长度。
现在,假设有一个线性函数M,您可以将其应用到椭圆的半轴A1和A2上,并将其转换(缩放)为半径等于次半轴的圆C,半径等于次半轴。椭圆的中心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 | <= | A2 |
仅当x在圆边界内时,等式成立。
如果线P在圆的平面内,则以下正弦检查将为您提供答案:
https://stackoverflow.com/a/1079478/9147444
如何计算线性函数M
一种简单的计算M的方法如下。使用椭圆的法向矢量N和半轴A1和A2创建3x3矩阵U。这样,U会将矢量A1,A2和N作为列。
然后缩放主要半轴A1,使其具有与次要半轴A2相同的长度。然后创建矩阵V auch,使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
关于java - Java:将两个椭圆段的交集转换为3d空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54552409/
运行 Tomcat 失败并出现 java.lang.OutOfMemoryError - 与缺少 PermGen 空间相关的错误。 我最近将 Tomcat 更改为以自己的用户(而非 root)运行。
我们有一个表,其中包含数百万行,其中包含 PostGIS 几何图形。我们要执行的查询是:落在边界几何内的最新条目是什么?这个查询的问题是我们经常会有大量的项目匹配边界框(半径大约为 5 公里),然后
我有一个Elasticsearch设置,它将允许用户搜索通配符作为索引。 array:3 [ "index" => "users" "type" => "user" "body" => arra
我创建了一个表,其中每行包含两个按钮,并且两个按钮连接在一起,我想将两个按钮分开。我用过 不起作用,css 也是,这是他们的另一种方式。 我有另一个问题,因为我不想在表格边框内显示操作按钮,而是在靠近
我试图在 jQuery Mobile 中的两个按钮之间留出空白。现实中的布局是这样的: Button 1 Button 2 (Hidden w/ display: none)
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
您好,我对图表应用程序还很陌生。现在我为我的应用程序创建了条形图。当我运行 create bar chart as separate project 时,输出如下所示。 然后当我将条形图与我的应用程序
我在使用 H2 和 GeoDB(内存中,junit)时遇到问题。 另外,使用 Hibernate 5(每个包的最新版本,包括 hibernate-spatial)和 Spring 4。 通过 id 实
我想画一张澳大利亚的 map ,并将每个城市表示为一个点。 然后突出显示人口众多(> 1M)的城市 library(sp) library(maps) data(canada.cities) head
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 6年前关闭。 Improve this
如何保持.txt文件中存在的空格?在.txt文件中,它表示: text :text text1 :text1 text23 :text2 text345 :text3 如果我写这段
以下哪个键最大? 选项 1:16 个数字 [0,9] 选项 2:30 个元音 选项 3:字母表中的 16 个字母 选项 4:32 位 有人可以帮助我,告诉我哪一个是正确的答案以及我们如何计算它吗?我知
在 Unity 3d 中使用 Azure 空间 anchor 来实现在 iOS 和 Android 上部署的室内和室外增强现实体验是否有益? 最佳答案 是的,对于 Azure Spatial Anch
我有一个绝对定位的圆形图像。图像只需占据屏幕宽度的 17%,并且距离顶部 5 个像素。 问题是,当我调整图像大小以占据屏幕宽度的 17% 时,它会这样做,但同时容器会变长。图像本身不会拉伸(stret
我在 Ubuntu 14.04 上使用 Cassandra。从文档中,我可以看到运行命令: nodetool snapshot 创建我的 key 空间的快照。 命令的输出是: nodetool sn
Heroku引入了“私有(private)空间”,是否可以将现有应用迁移到私有(private)空间? https://blog.heroku.com/archives/2015/9/10/herok
是否允许在语义记录中使用非绑定(bind)空格 或其他 HTML 编码字符?我遇到的问题是 ; 字符被软件视为记录的结尾。 例如:假设我有一份婚姻记录,其中包含 2 个结婚者的姓氏、结婚年份以及结
我正在研究“智能 parking ”项目,偶然发现了包含我们真正需要的YouTube视频。我们已经实现了第一部分,即从视频源进行实时透视变换,下一步是将其定义为一组矩形 我基本上需要知道他是如何做到的
我有两个类:Engine 和 Trainset(多个单元),这两个类共享其 ID 空间,其中包含名称和系列 id=- . 这是我的Engine类(它是抽象的,因为有引擎的子类型(DieselEngin
如果有人能帮助我,那就太好了。 我正在尝试使用Java的Split命令,使用空格分割字符串,但问题是,字符串可能没有空格,这意味着它将只是一个简单的顺序(而不是“输入2”将是“退出”) Scanner
我是一名优秀的程序员,十分优秀!