1. 程式人生 > >C語言-判斷線段是否與矩形範圍有交集

C語言-判斷線段是否與矩形範圍有交集

原文地址:http://blog.csdn.net/hbuxiaoshe/article/details/5833094

判斷線段AB是否與矩形範圍有交集

這裡的矩形指的是邊與座標軸平行的矩形,可用x和y上最大最小值表示。

判斷是否相交,先快速排斥,再做跨立,通過向量的叉積判斷矩形的四個頂點是否線上段的兩側,是說明有交集。

(如果判斷與矩形的邊是否有交集的話,可判斷線段是否與矩形的每條邊是否有交集,線段與線段的交集判斷。)

這裡在介紹另外一種方法,降維的方法:

例如,有線段AB和矩形MN,如圖所示:

通過M和N點的y座標計算直線AB上的D和C點,B和C點中取y值小的點B,A和D點中取y值大的點D,

最後確定了線段BD在x軸上的投影GH,矩形在x軸上的投影EF,判斷EF和GH是否有交集。

C語言程式碼如下:

/*
 * 判斷區間[x1, x2]和區間[x3, x4](x4可能小於x3)是否有交集,有返回1,無0
 */
int IntervalOverlap(double x1, double x2, double x3, double x4)
{
	double t;
	if (x3 > x4)
	{
		t = x3;
		x3 = x4;
		x4 = t;
	}
	
	if (x3 > x2 || x4 < x1)
		return 0;
	else
		return 1;
}

/*
 * 判斷矩形r和線段AB是否有交集,有返回1,無0
 */
int RSIntersection
(Rectangle r, Point A, Point B) { if (A.y == B.y) // 線段平行於x軸 { if (A.y <= r.ymax && A.y >= r.ymin) { return IntervalOverlap(r.xmin, r.xmax, A.x, B.x); } else { return 0; } } // AB兩點交換,讓B點的y座標最大 Point t; if (A.y > B.y) { t = A; A = B; B = t; } // 線上段AB上確定點C和D // 兩點確定一條直線: (x-x1)/(x2-x1)=(y-y1)/(y2-y1) double k = (B.x - A.x)/(B.y - A.y); Point C, D; if (A.y < r.ymin) { C.y = r.ymin; C.x = k * (C.y - A.y) + A.x; } else C = A; if (B.y > r.ymax) { D.y = r.ymax; D.x = k * (D.y - A.y) + A.x; } else D = B; if (D.y >= C.y) // y維上有交集 { return IntervalOverlap(r.xmin, r.xmax, D.x, C.x); } else { return 0; } }