关于求线段和线段,线段和圆弧,圆弧与圆弧的交点算法

1、线段与线段求交点

已知线段的起点和终点,求交点,这个比较简单,解2个二元一次方程可以求出。

a、我这里的算法是判断2条线段的定义域和值域是否有重合地方,有则进行下一步判断,没有这返回空,表示没有交点。

b、根据直线方程2点式y - y1 = (y2 - y1) / (x2 - x1)(x - x1),进行解方程,不过这之前先进行对斜率判段,分为斜率k不存在,k=0,k存在三种情况,

当然这里也可以分为2种情况,斜率存在与不存在。

c、最后解方程,求出根后,进行验证,验证是否在其值域和定义域内。

2、线段和圆弧求交点

已知线段的起点和终点,圆弧的圆心,弧的起点和弧长所对应角度(角度大于0表示逆时针偏移角度)

分析:圆弧有优弧和劣弧,顺时针和逆时针之别,所以这里用到一个带符号的角度来表示顺时针和逆时针。由于圆弧属于圆上的一段,我这里先用线段和圆的方程求交点,

再判断交点是否在圆弧上得出。

a、首先求圆弧的圆心到直线(线段)的距离d  = (Ax0 + By0 + C) / (A^2 + B^2),这里要先求出线段的直线方程,这里我们用的是直线的一般方程表示,

就暂时用考虑斜率的问题了。

直线方程的一般式:Ax + By + C = 0;其中ABC可以对(1)中的2点式方程化简算出ABC关于x1,y1,x2,y2的表达式。

b、在求出圆弧的半径r,半径的求法可以根据圆心与弧的起点的距离可以得知,先判断r与d的关系,若d <= r,就知道直线与圆有交点,否则返回空,表示没有交点。

c、有交点我们再进行进一步计算,这样一定程度上优化算法。我们就可以把直线方程带到圆的方程中了,再代入之前,必须的想考虑一下,若带入x,则的判断斜率k不存在的情况(x2 == x1),这种情况的拿出来单独考虑。若带入y,则判断斜率 k = 0 的情况(y2 == y1)。

圆的方程: (x - x0)^2 + (y - y0)^2 = r^2

d、考虑好之后就是解一个一元二次方程,如:(1 + A^2 / B^2)x^2 + (2AC / B^2 + 2y0A / B - 2x0)x + (x0^2 + y0^2 - r^2 + C^2 / B^2 + 2y0C / B) = 0;

这里解一元二次方程,就得用到求根公式x1 = (-b + sqrt(b^2 - 4ac)) / (2a), x2 = (-b - sqrt(b^2 - 4ac)) / (2a);这是为什么我把上式化成形如ax^2 + bx + c = 0方程。

这里解之前还得判断b^2 - 4ac 是否大于等于0,这里是高中的知识,权当复习一遍,>= 0表示有解, <0表示没有解,没有解,直接可以返回空,不用做后面的计算了。

c、这样可以求出直线和圆的交点,但我要求的是线段和圆弧,所以我们可以先判断这交点是否在线段上,这里只要判断一下它的定义域或者值域是否符合要求就行。

关键和难点在于判断点在圆弧上,网上在一个块的资料很少,大都是在圆上的,我尝试过2个方法,最后选择了这一种:判断圆弧起点角度是多少angle1,

这里的是以x轴的正方向为0°。在求出圆弧终点的角度angle2 = angle1 + angle(终点的角度等于起点角度加上弧长谁对应的角度)。最后是交点的角度angle3。

d、 角度求法:我是根据正切求出,因为我们只要知道2点坐标就行,这里起点都是圆心,所以很方便求出,也可以理解成求向量与x轴正方向的角度。

正切求出来的角度都是小于90度的,我是跟据向量坐标符号得知哪个像限,得知角度。

e、判断点是否在圆弧上,可以通过公司 angle1 < angle3 + 2 k PI < angle2,简单说就是判断交点角度是否在圆弧角度范围内,这里加了一个2 k PI,

其中PI表示3.1415926,高中数学判断角度范围都的加一个2k PI,这里是一样的原理,因为,角度求出来后有正负,甚至大于360度,通过角度求法的方式是0-360度,所以加一个2k PI只是让他们在同一判断条件下,我们只要对k进行3个取值判断就行分别是 -1,0,1。只有有一种满足不等式就可以判断在圆弧上了

(这里不理解的话最好通过画图解析一下,你可以通过下面的图带入公式好好分析一下就知道,为什么这么写了)。

f、判断是否在圆弧上后,就能得到所求的交点了。

3、圆弧和圆弧的交点

已知圆弧的圆心,弧的起点和弧长所对应角度(角度大于0表示顺时针偏移角度)

分析:2圆有相离、相切(内切和外切)、内含,首先要判断这两个关系,然后我们可以圆另一个方程:x^2 + y^2 + Dx  + Ey + F = 0。

其中的DEF是关于x0、y0、r的表达式,也就是上面圆的方程式化简所得。

a、首先求出2圆心的距离d,然后判断 |r1 - r2| <= d <= r1 + r2,只有满足这个式子,表示2圆有交点,否则没有交点。这也是高中的知识(或者是初中知识,这个我记得不太清楚了)。

b、知道有交点后,在进行下一步计算,就是解2圆的方程了,我化简得到的是:

(1 + (D - D1)^2 / (E1 - E)^2)x^2 + [2(F - F1)(D - D1) / (E1 - E)^2 + D + E(D - D1) / (E1 -  E)]x + [(F - F1)^2/ (E1 - E)^2 + E(F - F1) / (E1 - E) + F] = 0;

一样画成形如ax^2 + bx + c的形式,然后利用求根公式x1 = (-b + sqrt(b^2 - 4ac)) / (2a), x2 = (-b - sqrt(b^2 - 4ac)) / (2a);解之前还得判断b^2 - 4ac 是否大于等于0,

>= 0表示有解, <0表示没有解,没有解,直接可以返回空,不用做后面的计算了。

c、求出交点后,跟(2)的方式一样,验证交点是否都在这2圆弧上没有(这里不再累赘了,跟上面验证是一样的)。最后就可以得到我们想要的点了。



总结:

前面时算法一些分析,由于都是一个一个字码出来的,有什么问题还请理解,不懂得还可以留言给我,上面的式子是我以前算的,建议自己好好重新算一次,得到公式,这样更容易理解算法。

 下面是算法代码和测试程序的下载:

http://download.csdn.net/download/u012727080/10175508