Q?/strong>
判断点P是否在多边Ş中是计算几何中一个非常基本但是十分重要的法。以点P为端点,向左方作线LQ由于多边Ş是有界的Q所以射UL的左端一定在多边形外Q考虑沿着L从无I处开始自左向右移动,遇到和多边Ş的第一个交点的时候,q入C多边形的内部Q遇到第二个交点的时候,d了多边ŞQ?#8230;…所以很Ҏ看出当L和多边Ş的交Ҏ目C是奇数的时候,P在多边Ş内,是偶数的话P在多边Ş外?/p>
但是有些Ҏ情况要加以考虑。如图下?a)(b)(c)(d)所C。在?a)中,L和多边Ş的顶点相交,q时候交点只能计一个;在图(b)中,L和多边Ş点的交点不应被计算Q在?c)?d) 中,L和多边Ş的一条边重合Q这条边应该被忽略不计。如果L和多边Ş的一条边重合Q这条边应该被忽略不计?/p>
Zl一赯Q我们在计算线L和多边Ş的交点的时候,1。对于多边Ş的水q不作考虑Q?。对于多边Ş的顶点和L怺的情况,如果该顶Ҏ其所属的边上U坐标较大的点Q则计数Q否则忽略;3。对于P在多边Ş边上的情形,直接可判断P属于多边行。由此得出算法的伪代码如下:
count ← 0;
以P为端点,作从叛_左的线L;
for 多边形的每条边s
do if P在边s?nbsp;
then return true;
if s不是水^?
then if s的一个端点在L?
if 该端Ҏs两端点中U坐标较大的端点
then count ← count+1
else if s和L怺
then count ← count+1;
if count mod 2 = 1
then return true;
else return false;
其中做射UL的方法是Q设P'的纵坐标和P相同Q横坐标为正无穷大(很大的一个正敎ͼQ则P和P'q定了线L?
判断Ҏ否在多边形中的这个算法的旉复杂度ؓO(n)?/p>
另外q有一U算法是用带W号的三角Ş面积之和与多边Ş面积q行比较Q这U算法由于用QҎq算所以会带来一定误差,不推荐大家用?
判断U段是否在多边Ş?/strong>Q?/strong>
U段在多边Ş内的一个必要条件是U段的两个端炚w在多边Ş内,但由于多边Ş可能为凹Q所以这不能成ؓ判断的充分条件。如果线D和多边形的某条边内交(两线D内交是指两U段怺且交点不在两U段的端点)Q因为多边Ş的边的左右两侧分属多边Ş内外不同部分Q所以线D一定会有一部分在多边Ş?见图a)。于是我们得到线D在多边形内的第二个必要条gQ线D和多边形的所有边都不内交?
U段和多边Ş交于U段的两端点q不会媄响线D|否在多边形内Q但是如果多边Ş的某个顶点和U段怺Q还必须判断两相M点之间的U段是否包含于多边Ş内部Q反例见图b)?
因此我们可以先求出所有和U段怺的多边Ş的顶点,然后按照X-Y坐标排序(X坐标的排在前面Q对于X坐标相同的点QY坐标的排在前面Q这U排序准则也是ؓ了保证水q_垂直情况的判断正?Q这Lȝ两个点就是在U段上相ȝ两交点,如果L盔R两点的中点也在多边Ş内,则该U段一定在多边形内?
证明如下Q?/p>
命题1Q?
如果U段和多边Ş的两盔R交点P1 QP2的中点P' 也在多边形内Q则P1, P2之间的所有点都在多边形内?/p>
证明Q?
假设P1,P2之间含有不在多边形内的点Q不妨设该点为QQ在P1, P'之间Q因为多边Ş是闭合曲U,所以其内外部之间有界,而P1属于多边行内部,Q属于多边性外部,P'属于多边性内部,P1-Q-P'完全q箋Q所以P1Q和QP'一定跨多边Ş的边界,因此在P1,P'之间臛_q有两个该线D和多边形的交点Q这和P1P2是相M交点矛盾Q故命题成立。证毕?
由命?直接可得出推论:
推论2Q?
讑֤边Ş和线DPQ的交点依ơؓP1,P2,……PnQ其中Pi和Pi+1是相M交点Q线DPQ在多边Ş内的充要条g是:PQQ在多边Ş内且对于i =1, 2,……, n-1QPi ,Pi+1的中点也在多边Ş内?
在实际编E中Q没有必要计所有的交点Q首先应判断U段和多边Ş的边是否内交Q倘若U段和多边Ş的某条边内交则线D一定在多边形外Q如果线D和多边形的每一条边都不内交Q则U段和多边Ş的交点一定是U段的端Ҏ者多边Ş的顶点,只要判断Ҏ否在U段上就可以了?
x我们得出法如下Q?
if U端PQ的端点不都在多边形内
then return false;
炚wpointSet初始化ؓI?
for 多边形的每条边s
do if U段的某个端点在s?
then 该端点加入pointSet;
else if s的某个端点在U段PQ?
then 该端点加入pointSet;
else if s和线DPQ怺 // q时候已l可以肯定是内交?
then return false;
pointSet中的Ҏ照X-Y坐标排序;
for pointSet中每两个盔R?pointSet[i] , pointSet[ i+1]
do if pointSet[i] , pointSet[ i+1] 的中点不在多边Ş?
then return false;
return true;
q个q程中的排序因ؓ交点数目肯定q小于多边Ş的顶Ҏ目nQ所以最多是常数U的复杂度,几乎可以忽略不计。因此算法的旉复杂度也是O(n)?/p>
计算U段或直U与U段的交?/font>:
设一条线DؓL0 = P1P2Q另一条线D|直线为L1 = Q1Q2 Q要计算的就是L0和L1的交炏V?
1Q?首先判断L0和L1是否怺Q方法已在前文讨Q,如果不相交则没有交点Q否则说明L0和L1一定有交点Q下面就L0和L1都看作直U来考虑?
2Q?如果P1和P2横坐标相同,即L0q于Y?
a) 若L1也^行于Y_
i. 若P1的纵坐标和Q1的纵坐标相同Q说明L0和L1qQ假如L1是直U的话他们有无穷的交点,假如L1是线D늚话可?计算两条qU段的交?的算法求他们的交点(该方法在前文已讨Q;
ii. 否则说明L0和L1qQ他们没有交点;
b) 若L1不^行于Y_则交Ҏ坐标为P1的横坐标Q代入到L1的直U方E中可以计算Z点纵坐标Q?
3Q?如果P1和P2横坐标不同,但是Q1和Q2横坐标相同,即L1q于Y_则交Ҏ坐标为Q1的横坐标Q代入到L0的直U方E中可以计算Z点纵坐标Q?
4Q?如果P1和P2U坐标相同,即L0q于X?
a) 若L1也^行于X_
i. 若P1的横坐标和Q1的横坐标相同Q说明L0和L1qQ假如L1是直U的话他们有无穷的交点,假如L1是线D늚话可?计算两条qU段的交?的算法求他们的交点(该方法在前文已讨Q;
ii. 否则说明L0和L1qQ他们没有交点;
b) 若L1不^行于X_则交点纵坐标为P1的纵坐标Q代入到L1的直U方E中可以计算ZҎ坐标Q?
5Q?如果P1和P2U坐标不同,但是Q1和Q2U坐标相同,即L1q于X_则交点纵坐标为Q1的纵坐标Q代入到L0的直U方E中可以计算ZҎ坐标Q?
6Q?剩下的情况就是L1和L0的斜率均存在且不?的情?
a) 计算出L0的斜率K0QL1的斜率K1 Q?
b) 如果K1 = K2
i. 如果Q1在L0上,则说明L0和L1qQ假如L1是直U的话有无穷交点Q假如L1是线D늚话可?计算两条qU段的交?的算法求他们的交点(该方法在前文已讨Q;
ii. 如果Q1不在L0上,则说明L0和L1qQ他们没有交炏V?
c) 联立两直U的方程l可以解ZҎ
q个法q不复杂Q但是要分情况讨论清楚,其是当两条U段q的情况需要单独考虑Q所以在前文求两条qU段的算法单独写出来。另外,一开始就先利用矢量叉乘判断线D与U段Q或直线Q是否相交,如果l果是相交,那么在后面就可以线D全部看作直U来考虑。需要注意的是,我们可以直U或U段方程改写为ax+by+c=0的Ş式,q样一来上q过E的部分步骤可以合ƈQ羃短了代码长度Q但是由于先要求出参敎ͼq种法花Ҏ多的旉?
求线D|直线与圆的交?/font>:
讑֜心ؓOQ圆半径为rQ直U(或线D)L上的两点为P1,P2?
1. 如果L是线D且P1QP2都包含在圆O内,则没有交点;否则q行下一步?
2. 如果Lq于Y_
a) 计算圆心到L的距disQ?
b) 如果dis > r 则L和圆没有交点Q?
c) 利用勾股定理Q可以求Z交点坐标Q但要注意考虑L和圆的相切情c?
3. 如果Lq于X_做法与Lq于Y轴的情况cMQ?
4. 如果L既不qX轴也不^行Y_可以求出L的斜率KQ然后列出L的点斜式方程Q和圆方E联立即可求解出L和圆的两个交点;
5. 如果L是线D,对于2Q?Q?中求出的交点q要分别判断是否属于该线D늚范围内?/p>

]]>