如何确定GDI +中两条线的交点?
我正在使用.NET来创建一个具有绘图表面的应用程序,类似于Visio。 UI使用Graphics.DrawLine连接屏幕上的两个对象。 这个简单的实现工作正常,但随着表面变得更复杂,我需要一种更健壮的方式来表示对象。 这些强大要求之一是确定两条线的交叉点,因此我可以通过某种图形指示分离。
所以我的问题是,有人可以建议一种方法吗? 也许使用不同的技术(可能是GraphViz)或算法?
由y = mx + c表示的线对于计算机图形是有问题的,因为垂直线要求m是无穷大的。
此外,计算机图形中的线条具有起点和终点,而不像数学线条在范围上是无限的。 如果交叉点位于所讨论的两个线段上,则通常只对交叉线感兴趣。
如果你有两个线段,一个从向量x1到x1 + v1,一个从向量x2到x2 + v2,那么定义:
a = (v2.v2 v1.(x2-x1) - v1.v2 v2.(x2-x1)) / ((v1.v1)(v2.v2) - (v1.v2)^2) b = (v1.v2 v1.(x2-x1) - v1.v1 v2.(x2-x1)) / ((v1.v1)(v2.v2) - (v1.v2)^2)
其中对于向量p =(px,py),q =(qx,qy),pq是点积(px * qx + py * qy)。 首先检查(v1.v1)(v2.v2)=(v1.v2)^ 2 – 如果是,则线是平行的并且不交叉。
如果它们不是平行的,那么如果0 <= a <= 1且0 <= b <= 1,则交点位于两个线段上,并由点给出
x1 + a * v1
编辑 a和b的等式的推导如下。 交点满足矢量方程
x1 + a*v1 = x2 + b*v2
通过将此等式的点积与v1
和v2
,我们得到两个等式:
v1.v1*a - v2.v1*b = v1.(x2-x1) v1.v2*a - v2.v2*b = v2.(x2-x1)
它形成了a和b的两个线性方程。 求解该系统(通过将第一个等式乘以v2.v2而将第二个等式乘以v1.v1并减去或以其他方式)得到a和b的等式。
问博士。 数学
如果旋转参照系以与第一个线段对齐(因此原点现在是第一条线的起点,第一条线的矢量沿X轴延伸)问题就变成了,第二条线在哪里在新坐标系中击中X轴。 这是一个更容易回答的问题。 如果第一行被称为A
并且它被AO
定义为行的原点而’AV’是行的向量,那么AO + AV
是该行的终点。 参考框架可以由矩阵定义:
| AVX AVY AOX | M = | AVY -AVX AOY | | 0 0 1 |
在齐次坐标系中,该矩阵为参考系提供了基础,该参照系在X轴上将线A
映射到0到1。 我们现在可以将变换后的线B
定义为:
CO = M*(BO) CV = M*(BO + BV) - CO
*
运算符正确定义为齐次坐标(在这种情况下从3个空间到2个空间的投影)。 现在剩下的就是检查并查看C
到达X轴的位置,这与解决Y
的参数方程式的Y
侧相同:
COY + t * CVY = 0 -COY t = -------- CVY
如果t
在0到1的范围内,则C
命中线段内的X轴。 它落在X轴上的位置由C
的参数方程的X侧给出:
x = COX + t * CVX
如果x
在0到1的范围内,则交点位于A
线段上。 然后我们可以在原始坐标系中找到以下点:
p = AO + AV * x
您当然必须首先检查是否有任何线段长度为零。 此外,如果CVY = 0
您有平行线段。 如果CVX
也为零,则您有共线线段。