POJ 1127题解

"ACM计算几何习题"

Posted by jhljx on July 21, 2016

目录

题目描述
判断点在直线上的方法
判断点在线段上的方法
Reference

题目描述

给出了平面上的n条线段,然后给出m对线段的下标对\((i,j)\),判断第i条和第j条线段是否相连。
比较坑的地方是:不同线段之间可能间接相连,即通过别的线段依次传递,最终使得两条线段相连。

判断点在直线上的方法

向量a=(x3-x1,y3-y1),向量b=(x2-x1,y2-y1)
\(a \times b > 0\)表示点(x3,y3)在直线(x1,y1)-(x2,y2)的逆时针方向
\(a \times b < 0\)表示点(x3,y3)在直线(x1,y1)-(x2,y2)的顺时针方向
\(a \times b = 0\)表示点(x3,y3)在直线(x1,y1)-(x2,y2)上

struct point{  
   double x,y;  
}  
double direct(point p1, point p2, point p3){  
    return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);  
}  
bool onLine(point p1, point p2, point p3){  
    return direct(p1,p2,p3) == 0;  
}  

判断点在线段上的方法

判断点在线段上有很多种方法:
第一种,通过向量外积先判断点是否在直线上,然后判断点的x和y是否在线段的x和y范围内。

struct point{  
   double x,y;  
}  
double direct(point p1, point p2, point p3) {  
    return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);  
}  
bool onSegment(point p1, point p2, point p3) {
    return (min(p1.x, p2.x) <= p3.x && p3.x <= max(p1.x, p2.x) && min(p1.y, p2.y) <= p3.y 
	&& p3.y <= max(p1.y, p2.y)) && direct(p1, p2, p3) == 0;
}

其中,onSegment函数用来判断第三个点是否在第一,二个点构成的线段上。

第二种,通过向量外积先判断点是否在直线上,然后用向量内积判断点是否在线段上。

struct point{
   double x,y;
}
double det(point p1, point p2, point p3) {
    return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
}
double dot(point p1, point p2, point p3, point p4) {
    return (p2.x - p1.x) * (p4.x - p3.x) - (p2.y - p1.y) * (p4.y - p3.y);
}
bool onSegment(point p1, point p2, point p3) {
    return det(p1, p2, p3) == 0 && dot(p1, p3, p2, p3) <= 0;
}

其中,det函数用来计算向量p1p2叉乘p1p3,dot函数用来计算向量p1p2点乘p3p4,onSegment函数用来判断p3是否在p1p2构成的线段上。