谈谈"求线段交点"的几种算法

如题所述

第1个回答  2022-10-29

  求线段交点 是一种非常基础的几何计算 在很多游戏中都会被使用到

  下面我就现学现卖的把最近才学会的一些 求线段交点 的算法说一说 希望对大家有所帮助

  本文讲的内容都很初级 主要是面向和我一样的初学者 所以请各位算法帝们轻拍啊 嘎嘎

  引用已知线段 (a b) 和线段 (c d) 其中a b c d为端点 求线段交点p (平行或共线视作不相交)

  算法一 求两条线段所在直线的交点 再判断交点是否在两条线段上

  求直线交点时 我们可通过直线的一般方程 ax+by+c= 求得(方程中的abc为系数 不是前面提到的端点 另外也可用点斜式方程和斜截式方程 此处暂且不论)

  然后根据交点的与线段端点的位置关系来判断交点是否在线段上 公式如下图

    

【责编:at 】

  算法二 判断每一条线段的两个端点是否都在另一条线段的两侧 是则求出两条线段所在直线的交点 否则不相交

  第一步判断两个点是否在某条线段的两侧 通常可采用投影法

  求出线段的法线向量 然后把点投影到法线上 最后根据投影的位置来判断点和线段的关系 见下图

   

  点a和点b在线段cd法线上的投影如图所示 这时候我们还要做一次线段cd在自己法线上的投影(选择点c或点d中的一个即可)

  主要用来做参考

  图中点a投影和点b投影在点c投影的两侧 说明线段ab的端点在线段cd的两侧

  同理 再判断一次cd是否在线段ab两侧即可

  求法线 求投影 什么的听起来很复杂的样子 实际上对于我来说也确实挺复杂 在几个月前我也不会(念书那会儿的几何知识都忘光了 ( ) 不过好在学习和实现起来还不算复杂 皆有公式可循

  求线段ab的法线

  JavaScript Code复制内容到剪贴板var nx=b y a y ny=a x b x var normalLine = {  x nx y ny } 注意 其中 normalLine x和normalLine y的几何意义表示法线的方向 而不是坐标

  求点c在法线上的投影位置

  JavaScript Code复制内容到剪贴板var dist= normalLine x*c x + normalLine y*c y

  注意 这里的 投影位置 是一个标量 表示的是到法线原点的距离 而不是投影点的坐标

  通常知道这个距离就足够了

  当我们把图中 点a投影(distA) 点b投影(distB) 点c投影(distC) 都求出来之后 就可以很容易的根据各自的大小判断出相对位置

  distA==distB==distC 时 两条线段共线distA==distB!=distC 时 两条线段平行distA 和 distB 在distC 同侧时 两条线段不相交

  distA 和 distB 在distC 异侧时 两条线段是否相交需要再判断点c点d与线段ab的关系

  前面的那些步骤 只是实现了 判断线段是否相交 当结果为true时 我们还需要进一步求交点

  求交点的过程后面再说 先看一下该算法的完整实现

  JavaScript Code复制内容到剪贴板function segmentsIntr(a b c d){

  //线段ab的法线N var nx = (b y a y) ny = (a x b x)

  //线段cd的法线N var nx = (d y c y) ny = (c x d x)

  //两条法线做叉乘 如果结果为 说明线段ab和线段cd平行或共线 不相交var denominator = nx *ny ny *nx if (denominator== ) { return false }

  //在法线N 上的投影var distC_N =nx * c x + ny * c y var distA_N =nx * a x + ny * a y distC_N var distB_N =nx * b x + ny * b y distC_N

  // 点a投影和点b投影在点c投影同侧 (对点在线段上的情况 本例当作不相交处理) if ( distA_N *distB_N >=   ) { return false }

  // //判断点c点d 和线段ab的关系 原理同上// //在法线N 上的投影var distA_N =nx * a x + ny * a y var distC_N =nx * c x + ny * c y distA_N var distD_N =nx * d x + ny * d y distA_N if ( distC_N *distD_N >=   ) { return false }

  //计算交点坐标var fraction= distA_N / denominator var dx= fraction * ny dy= fraction * nx return { x a x + dx y a y + dy } }

  最后 求交点坐标的部分 所用的方法看起来有点奇怪 有种摸不著头脑的感觉

  其实它和算法一 里面的算法是类似的 只是里面的很多计算项已经被提前计算好了

  换句话说 算法二里求交点坐标的部分 其实也是用的直线的线性方程组来做的

  现在来简单粗略 很不科学的对比一下算法一和算法二 最好情况下 两种算法的复杂度相同 最坏情况 算法一和算法二的计算量差不多 但是算法二提供了 更多的 提前结束条件 所以平均情况下 应该算法二更优

  实际测试下来 实际情况也确实如此

【责编:at 】

  算法三 判断每一条线段的两个端点是否都在另一条线段的两侧 是则求出两条线段所在直线的交点 否则不相交

  (咦? 怎么感觉和算法二一样啊? 不要怀疑 确实一样 …… 囧)

  所谓算法三 其实只是对算法二的一个改良 改良的地方主要就是 不通过法线投影来判断点和线段的位置关系 而是通过点和线段构成的三角形面积来判断

  先来复习下三角形面积公式 已知三角形三点a(x y) b(x y) c(x y) 三角形面积为

  JavaScript Code复制内容到剪贴板var triArea=( (a x c x) * (b y c y) (a y c y) * (b x c x) ) /

  因为 两向量叉乘==两向量构成的平行四边形(以两向量为邻边)的面积 所以上面的公式也不难理解

  而且由于向量是有方向的 所以面积也是有方向的 通常我们以逆时针为正 顺时针为负数

  改良算法关键点就是 如果 线段ab和点c构成的三角形面积 与 线段ab和点d构成的三角形面积 构成的三角形面积的正负符号相异 那么点c和点d位于线段ab两侧 如下图所示

【责编:at 】 lishixinzhi/Article/program/Java/Javascript/201311/25424

谈谈"求线段交点"的几种算法
求直线交点时 我们可通过直线的一般方程 ax+by+c= 求得(方程中的abc为系数 不是前面提到的端点 另外也可用点斜式方程和斜截式方程 此处暂且不论)然后根据交点的与线段端点的位置关系来判断交点是否在线段上 公式如下图 【责编:at 】算法二 判断每一条线段的两个端点是否都在另一条线段的两侧 ...

两线段交点怎么求?
两线段交点的求解通常涉及到线性方程的解析。在二维平面上,假设有两条线段AB和CD,它们的端点分别由坐标A(x1, y1), B(x2, y2)和C(x3, y3), D(x4, y4)给出。要求解这两条线段是否相交以及交点(如果存在)的坐标,可以采用以下步骤:首先写出两条线段所在直线的方程。线段AB可以表示为直线的...

求线段焦点,最简单算法
如果存在一对正实数n<=1,m<=1,使得A+nx=B+my成立,则相交,否则不相交。得到方程组:a1+n*x1=b1+m*y1 a2+n*x2=b2+m*y2 关于n,m的方程组,如果有解则相交,交点坐标为A+nx。情况2:已知两条线段四个端点的坐标 化为情况1,再求解。

两线段交点坐标公式如何使用?
交点坐标:(x, y) = ((b2 - b1) \/ (k1 - k2), k1 * (b2 - b1) \/ (k1 - k2) + b1)这就是两线段交点坐标公式的使用方法。需要注意的是,这个方法只适用于两条不平行的直线。如果两条直线平行,那么它们的斜率相等(k1 = k2),此时分母为0,无法求解。在这种情况下,两条直线没有...

已知四个点,求线段的交点坐标。
这是一个简单的用向量求点的坐标的问题。如:由p1p8=a*p1p4,可得(x8-x1,y8-y1)=a(x4-x1,y4-y1),从而x8=x1+a(x4-x1),y8=y1+a(y4-y1)。同理,x6=x2+a(x3-x2),y6=y2+a(y3-y2)。又由条件易知,p8p=b*p8p6,从而有x=x8+b(x6-x8)=x1+a(x4-x1)+b[x2-x1+a...

直线和2点的线段相交求交点, 等分比
x2-x0)^2+(y2-y0)^2 点1到直线距离=ax1+by1+c 点2到直线距离=ax2+by2+c 则有:到点1的距离\/到点2的距离=点1到直线距离\/点2到直线距离 即:根下(x1-x0)^2+(y1-y0)^2\/根下(x2-x0)^2+(y2-y0)^2=(ax1+by1+c)\/(ax2+by2+c)解等式,可求交点坐标。

两条线段的两端坐标,怎样求这两条线段交点坐标
第一步:根据每两条线段端点坐标,求出每一条线段所在直线的解析式;第二步:根据所得两个解析式联立方程组,解方程组 根据这组解就可以得到两条线段的交点坐标!

如何求任意一条直线的中点
求中点的步骤如下:首先,我们以点A和B为圆心,分别画半径大于线段AB长度一半的圆。具体来说,以A为圆心,以AB长度的一半为半径画圆;以B为圆心,以同样长度为半径画圆。两个圆必然相交于两点。接着,寻找这两个交点,记为C和D。这两个交点分别位于线段AB的两侧。最后,通过连接这两点C和D,我们...

怎么求两条双曲线的交点个数
1、使用点差法求两条双曲线的交点个数。点差就是在求解圆锥曲线并且题目中交代直线与圆锥曲线相交被截的线段中点坐标的时候,利用直线和圆锥曲线的两个交点,并把交点代入圆锥曲线的方程,并作差。求出直线的斜率,然后利用中点求出直线方程。是解决椭圆与直线的关系中常用到的一种方法;2、直接联立方程...

怎么求射线和线段的交点
即是看看α是不是在这个范围内,如果在,一定能够相交。求交点:判断相交后,点一定在线段上,已知了线段的起始点这两个点,可以把线段所在的直线求出,知道了射线起点和射线斜率α ,射线所在的直线也可以求出,问题就转化为了求解两条直线的交点,解个二元一次方程组即可。如不满意,请追问。

相似回答
大家正在搜