下面小编就最近学会的一些”求线段交点”的算法说一说, 希望对大家有所帮助。“求线段交点”是一种非常基础的几何计算, 在很多游戏中都会被使用到。有需要的可以参考学习
本文讲的内容都很初级, 主要是面向和我一样的初学者, 所以请各位算法帝们轻拍啊
算法一: 求两条线段所在直线的交点, 再判断交点是否在两条线段上.
求直线交点时 我们可通过直线的一般方程 ax+by+c=0 求得(方程中的abc为系数,不是前面提到的端点,另外也可用点斜式方程和斜截式方程,此处暂且不论).
然后根据交点的与线段端点的位置关系来判断交点是否在线段上.
// 如果分母为0 则平行或共线, 不相交 /** 2 判断交点是否在两条线段上 **/ // 且交点也在线段2上
算法一思路比较清晰易懂, 但是性能并不高. 因为它在不确定交点是否有效(在线段上)之前, 就先去计算了交点, 耗费了较多的时间.
如果最后发现交点无效, 那么之前的计算就白折腾了. 而且整个计算的过程也很复杂.
那么有没有一种思路,可以让我们先判断是否存在有效交点,然后再去计算它呢?
显然答案是肯定的. 于是就有了后面的一些算法.
算法二: 判断每一条线段的两个端点是否都在另一条线段的两侧, 是则求出两条线段所在直线的交点, 否则不相交.
第一步判断两个点是否在某条线段的两侧, 通常可采用投影法:
求出线段的法线向量, 然后把点投影到法线上, 最后根据投影的位置来判断点和线段的关系.
点a和点b在线段cd法线上的投影如图所示, 这时候我们还要做一次线段cd在自己法线上的投影(选择点c或点d中的一个即可).
图中点a投影和点b投影在点c投影的两侧, 说明线段ab的端点在线段cd的两侧.
同理, 再判断一次cd是否在线段ab两侧即可.
求法线 , 求投影 什么的听起来很复杂的样子, 实际上对于我来说也确实挺复杂,在几个月前我也不会(念书那会儿的几何知识都忘光了 :'( )'
不过好在学习和实现起来还不算复杂, 皆有公式可循
求点c在法线上的投影位置:
注意: 这里的"投影位置"是一个标量, 表示的是到法线原点的距离, 而不是投影点的坐标.
通常知道这个距离就足够了.
当我们把图中 点a投影(distA),点b投影(distB),点c投影(distC) 都求出来之后, 就可以很容易的根据各自的大小判断出相对位置.
前面的那些步骤, 只是实现了"判断线段是否相交", 当结果为true时, 我们还需要进一步求交点.
求交点的过程后面再说, 先看一下该算法的完整实现 :
//两条法线做叉乘, 如果结果为0, 说明线段ab和线段cd平行或共线,不相交 //在法线N2上的投影 // 点a投影和点b投影在点c投影同侧 (对点在线段上的情况,本例当作不相交处理); //判断点c点d 和线段ab的关系, 原理同上 //在法线N1上的投影
最后 求交点坐标的部分 所用的方法看起来有点奇怪, 有种摸不着头脑的感觉.
其实它和算法一 里面的算法是类似的,只是里面的很多计算项已经被提前计算好了.
换句话说, 算法二里求交点坐标的部分 其实也是用的直线的线性方程组来做的.
现在来简单粗略 很不科学的对比一下算法一和算法二:
实际测试下来, 实际情况也确实如此.
前面的两种算法基本上是比较常见的可以应付绝大多数情况. 但是事实上还有一种更好的算法.
这也是我最近才新学会的(我现学现卖了,大家不要介意啊…)
算法三: 判断每一条线段的两个端点是否都在另一条线段的两侧, 是则求出两条线段所在直线的交点, 否则不相交.
(咦? 怎么感觉和算法二一样啊? 不要怀疑 确实一样 … 囧)
所谓算法三, 其实只是对算法二的一个改良, 改良的地方主要就是 :
不通过法线投影来判断点和线段的位置关系, 而是通过点和线段构成的三角形面积来判断.
因为 两向量叉乘==两向量构成的平行四边形(以两向量为邻边)的面积 , 所以上面的公式也不难理解.
而且由于向量是有方向的, 所以面积也是有方向的, 通常我们以逆时针为正, 顺时针为负数.
如果”线段ab和点c构成的三角形面积”与”线段ab和点d构成的三角形面积” 构成的三角形面积的正负符号相异,
那么点c和点d位于线段ab两侧.
图中虚线所示的三角形, 缠绕方向(三边的定义顺序)不同, 所以面积的正负符号不同.
由于我们只要判断符号即可, 所以前面的三角形面积公式我们就不需要后面的 除以2 了.
// 面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理); // 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.
最后 计算交点坐标的部分 和算法二同理.
算法三在算法二的基础上, 大大简化了计算步骤, 代码也更精简. 可以说,是三种算法里, 最好的.实际测试结果也是如此.
当然必须坦诚的来说, 在Javascript里, 对于普通的计算, 三种算法的时间复杂度其实是差不多的(尤其是V8引擎下).
我的测试用例里也是进行变态的百万次级别的线段相交测试 才能拉开三种算法之间的差距.
不过本着精益求精 以及学习的态度而言, 追求一个更好的算法, 总是有其积极意义的。以上就是利用js实现线段交点的几种算法,内容不是很深奥,希望对大家学习js有所帮助。
基础巩固 能力提升 变式训练 拓展培优 真题演练
3. 某同学把一块三角形的玻璃打碎成了3块,现在要到玻璃店去配一块完全一样的玻璃,那么最省事的方法是( ).
1. 根据下列已知条件,能画出唯一的△ABC的是( )
A . 一个锐角对应相等 B . 两个锐角对应相等 C . 一条边对应相等 D . 斜边及一条直角边对应相等
3. 如图,∠ABC,∠ACB的平分线相交于点F,过点F作DE∥BC,交AB于D,交AC于E,那么下列结论正确的是:①△BDF,△CEF都是等腰三角形;②DE=BD+CE;③△ADE的周长为AB+AC;④BD=CE;( )
1. 已知:如图,CD⊥AB于D,BE⊥AC于E,∠1=∠2.求证:OB=OC.
2. 如图示,点B在AE上,∠CBE=∠DBE,要使△ABC≌△ABD, 还需添一个条件.
3. 如图,点 , 分别在
1. 已知点 为抛物线 上一动点,以 为顶点,且经过原点 的抛物线,记作“ ”,设其与 轴另一交点为 ,点 的横坐标为 .
为直角三角形时,求 的值.
为等边三角形时,求此时“
(2) 若 点的横坐标分别为1,2,3,…… ( 为正整数)时,抛物线“ ”,设其与 轴另一交点分别为 作 轴的垂线,垂足分别为
的坐标;(用含 的代数式表示)
?若存在,求 的值;若不存在,说明理由.
2. (教材呈现)如图,在 中,D是边BC的中点,过点C画直线CE,使 ,交AD的延长线于点E,求证:
(两直线平行,内错角相等).
(全等三角形的对应边相等).
(1) (方法应用)如图①,在 ,则BC边上的中线AD长度的取值范围是.
(2) (猜想证明)如图②,在四边形ABCD中, ,点E是BC的中点,若AE是 的平分线,试猜想线段AB、AD、DC之间的数量关系,并证明你的猜想;
(3) (拓展延伸)如图③,已知 ,点E是BC的中点,点D在线段AE上,
(1) 如图①,△PAM是等边三角形,在边PM上取点B(点B不与点P,M重合),连接AB,将线段AB绕点A逆时针旋转60°,得到线段AC,连接BC,MC.
①△MAC可以看作△PAB绕点逆时针旋转(度)得到的;
, 在边PM上取点B(点B不与点P,M重合),连接AB,将线段AB绕点A旋转,得到线段AC,旋转角为α,连接PC,BC.
, 求△PBC面积的最大值(直接写出结果即可).
1. 如图,在边长为2的等边 边上的中点,以点 为圆心, 分别交于 , 两点,则图中阴影部分的面积为( )
, 请你添加一个条件,使≌.
第二讲 直线、线段、射线
1、 理解线段、射线、直线的概念以及表示方法。
2、 定理1:两点确定一条直线。
3、 定理2:两点之间所有连线中线段最短。
4、 借助尺规比较两线段的长短。
5、 能用圆规做一条线段等于已知线段。
6、 重点掌握线段中点、等分点,求线段的长度。
(1)线段的概念:铅笔、人行横道线和路旁的电线杆都可以近似地看做线段。
(2)线段的表示方法:如图1,用两个大写字母表示,记做线段AB或线段BA;如图2,用一个小写字母表示,记做线段a。
(3)两点间的距离:连结两点的线段的长度叫做这两点的距离。
(4)线段公理:所有连接两点的线中,线段最短,即两点之间线段最短。
注意:①线段AB和线段BA是同一条线段;②连结AB就是画以A、B为端点的线段;③延长线段AB是指按从A到B的方向延长,如图所示,也可以说成反向延长BA。线段的延长线常常画成虚线。
(5)线段大小的比较:①度量法。先量出线段AB、线段CD的长度,根据它们的长度(数量)进行比较,线段大小关系与它们的长度关系是一致的。②叠合法。③圆规法。。
(6)线段的中点及等分点的概念:如图1所示,点B把线段AC分成两条相等的线段,点B叫做线段AC的中点。
有AB=BC=。如图2所示,点B和点C把线段AD分成三条相等的线2
段,点B、点C叫做线段AD的
三等分点,有AB=BC=CD=AD。类似的还有线段的四等分点、五等分点3
(1)射线的概念:直线上的一点和它一旁的部分叫做射线,这个点叫做射线的端点。
(2)射线的表示方法:用射线的端点和射线上任一点来表示,如图1中的射线记做射线OA或射线),转载请保留网址和出处