参考资料:《ACM/ICPC程序设计与分析》
判断点在线段上这个算法非常的简单,只要学过叉乘(CrossProduct)就很容易搞定
设点为Q,线段为P1P2,判断点Q是否在P1P2上。
算法依据:
1.点Q首先要在P1P2所在的直线上。
比较原始的办法是利用P1P2的坐标做出直线方程,然后代入点Q看是否满足方程,这样代码稍微麻烦些。
简单点就是用叉乘,如果点Q在P1P2直线上,那么:
P1Q x P1P2 = 0(x代表叉乘)
这个代码实现很容易。
P x Q = P.x * Q.y - P.y * Q.x(交叉相乘)PS:叉积的结果还是一个向量,二维向量的叉积是垂直于两个向量形成的平面的一个向量。这行公式实际上求的是标量。
2.Q要在以P1P2为对角线的平行矩形内
这个就更简单了,做一下比较即可
下面给出伪代码:
<span style="font-family:Microsoft YaHei;font-size:14px;">bool On_Segment(Point P1,Point P2,Point Q)
{
int condition1 = condition2 = 0
if(CrossProduct(P1Q,P1P1) == 0)//条件1
condition1 = 1;
if((min(P1.x,P2.x) <= Q.x) && (Q.x <= max(P1.x,P2.x)) &&
(min(P1.y,P2.y) <= Q.y) && (Q.y <= max(P1.y,P2.y)))//条件2
condition2 = 1;
if(condition1 && condition2)
return true;
else
return false;
}</span>
如果给出三点ABC,其位置关系如下:
给出求AB x AC叉乘的伪代码
<span style="font-family:Microsoft YaHei;font-size:14px;">double CrossProduct(Point A,Point B,Point C)
{
return (B.x - A.x) * (C.y - A.y) - (C.x - A.x) * (B.y - A.y);
}
</span>
有了这些基础,就可以对折线段的拐向进行判断
对于有公共端点的线段AB,BC,通过计算AB x AC可以确定AB的拐向
图示情况为AB x AC > 0 即AB在B点向左侧拐向C
图示情况为AB x AC < 0 即AB在B点拐向右侧后到C
不要忘了AB x AC == 0 的情况,此时ABC共线。