1. 程式人生 > >關於求線段和線段,線段和圓弧,圓弧與圓弧的交點演算法

關於求線段和線段,線段和圓弧,圓弧與圓弧的交點演算法

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