計算幾何札記 線段交

2021-06-18 11:42:30 字數 2988 閱讀 4735

叉積求面積和直線交點座標模板:

int n;

struct point

;point a[max], b[max], c[max], d[max], p[max][max];

double area[max][max], ans;

point getpoint(point p1, point p2, point p3, point p4)//已知四個點求直線相交的點的座標

//(這種求法包括了直線斜率不存在或為0的情況下)

void getpoints()

for (i = 2; i < n + 2; ++i)//獲取矩陣中間的點的座標

}}double getarea(point p1, point p2, point p3, point p4)//已知四個點的座標求四邊形的面積

ar = ar / 2.0;//要除以2.0

if (ar < 0)//面積是正數

return ar;

}void getareas()}}

}

計算幾何的線段交分為兩個步驟:快速排斥和跨立

[以下摘抄]

(1)       快速排斥試驗

設以線段 p1p2 為對角線的矩形為r1, 設以線段 q1q2 為對角線的矩形為r2,如果r1和r2不相交,則兩線段不會有交點;

(2)       跨立試驗。

如果兩線段相交,則兩線段必然相互跨立對方,所謂跨立,指的是一條線段的兩端點分別位於另一線段所在直線的兩邊。判斷是否跨立,還是要用到向量叉積的幾何意義。以圖3為例,若p1p2跨立q1q2 ,則向量 ( p1 - q1 ) 和( p2 - q1 )位於向量( q2 - q1 ) 的兩側,即:

( p1 - q1 ) × ( q2 - q1 ) * ( p2 - q1 ) × ( q2 - q1 ) < 0

上式可改寫成:

( p1 - q1 ) × ( q2 - q1 ) * ( q2 - q1 ) × ( p2 - q1 ) > 0

當 ( p1 - q1 ) × ( q2 - q1 ) = 0 時,說明線段p1p2和q1q2共線(但是不一定有交點)。同理判斷q1q2跨立p1p2的依據是:

( q1 - p1 ) × ( p2 - p1 ) * ( q2 - p1 ) × ( p2 - p1 ) < 0

具體情況如下圖所示:

圖3 直線段跨立試驗示意圖

根據向量叉積的幾何意義,跨立試驗只能證明線段的兩端點位於另乙個線段所在直線的兩邊,但是不能保證是在另一直線段的兩端,因此,跨立試驗只是證明兩條線段有交點的必要條件,必需和快速排斥試驗一起才能組成直線段相交的充分必要條件。根據以上分析,兩條線段有交點的完整判斷依據就是:1)以兩條線段為對角線的兩個矩形有交集;2)兩條線段相互跨立。

判斷直線段跨立用計算叉積演算法的crossproduct()函式即可,還需要乙個判斷兩個矩形是否有交的演算法。矩形求交也是最簡單的求交演算法之一,原理就是根據兩個矩形的最大、最小座標判斷。圖4展示了兩個矩形沒有交集的各種情況:

圖4 矩形沒有交集的幾種情況

圖5展示了兩個矩形有交集的各種情況:

圖5 矩形有交集的幾種情況

從圖4和圖5可以分析出來兩個矩形有交集的幾何座標規律,就是在x座標方向和y座標方向分別滿足最大值最小值法則,簡單解釋這個法則就是每個矩形在每個方向上的座標最大值都要大於另乙個矩形在這個座標方向上的座標最小值,否則在這個方向上就不能保證一定有位置重疊。由以上分析,判斷兩個矩形是否相交的演算法就可以如下實現:

186bool isrectintersect(

const rect& rc1,

const rect& rc2)

187完成了排斥試驗和跨立試驗的演算法,最後判斷直線段是否有交點的演算法就水到渠成了:

204bool islinesegmentintersect(

const lineseg& ls1,

const lineseg& ls2)

205210

//( p1 - q1 ) ×'a1?( q2 - q1 )

211double p1xq = crossproduct(ls1.ps.x- ls2.ps.x, ls1.ps.y- ls2.ps.y,

212                                ls2.pe.x- ls2.ps.x, ls2.pe.y- ls2.ps.y);

213//( p2 - q1 ) ×'a1?( q2 - q1 )

214double p2xq = crossproduct(ls1.pe.x- ls2.ps.x, ls1.pe.y- ls2.ps.y,

215                                ls2.pe.x- ls2.ps.x, ls2.pe.y- ls2.ps.y);

216217

//( q1 - p1 ) ×'a1?( p2 - p1 )

218double q1xp = crossproduct(ls2.ps.x- ls1.ps.x, ls2.ps.y- ls1.ps.y,

219                                ls1.pe.x- ls1.ps.x, ls1.pe.y- ls1.ps.y);

220//( q2 - p1 ) ×'a1?( p2 - p1 )

221double q2xp = crossproduct(ls2.pe.x- ls1.ps.x, ls2.pe.y- ls1.ps.y,

222                                ls1.pe.x- ls1.ps.x, ls1.pe.y- ls1.ps.y);

223224

//跨立實驗

225return

((p1xq* p2xq <=

0.0)

&&(q1xp * q2xp <=

0.0));

226}

islinesegmentexclusive()函式就是呼叫isrectintersect()函式根據結果做排斥判斷,此處不再列出**。

計算幾何 線段

首先是直線相交,這個簡單,就是看斜率,斜率不同則相交。重點分析線段與線段相交,給你兩組座標p1 x1,y1 p2 x2,y2 q1 x3,y3 q2 x4,y4 判斷p1p2與q1q2是否相交 首先可以很快排除下面四種情況 對於第 種情況滿足條件 max q1.x,q2.x max q1.x,q2....

計算幾何 線段相交

問題描述 已知兩條線段p1p2和q1q2,判斷p1p2和q1q2是否相交,若相交,求出交點。兩條線段的位置關係可以分為三類 有重合部分 無重合部分但有交點 無交點。演算法的步驟如下 1.快速排斥實驗。設以線段p1p2為對角線的矩形為r,設以線段q1q2為對角線的矩形為t,如果r和t不相交,則兩線段不...

LA3263計算幾何 尤拉定理的應用 線段交判邊

1 la3263計算幾何 尤拉定理的應用 線段交判邊 2尤拉定理 頂點 邊數 面數 2 3思路 先找到列舉的範圍,減少判斷的集合,再篩選。4巧妙之處 線段間產生的點如果被夾在原先定點的連線上,則產生一條新的邊 5易錯處 61 給出的第乙個點和最後乙個點是重合的,所以最終有n 1個初始點 72 應該統...