逆时针方向
给定3个点,构造出从同一起点的两条线段,判断两条线段的关系
这个关系包括逆时针、顺时针、重合,其中重合又包括点在线段正上方、正下方情况!
图示
图中都是以p0为源点,p0p1为基准线,判断p0p2相对p0p1的位置关系!
怎么只通过3个点的坐标来判断呢?
我们还是以向量的形式,运用向量的知识进行判断,需要用到向量的内积、外积知识不了解点击下方链接!
首线上面这些问题都可以归结到判断是否是逆时针方向问题!
判断逆时针
向量a、b的外积模为 |axb|=|a|x|b|sinθ,0<θ<180° sinθ>0,也就是从向量a出发逆时针旋转θ(右手螺旋定则),0<θ<180°时我们可以看出向量b在向量a的逆时针方向!
通过上述描述,我们可以运用向量的外积模,如果外积模>0,则向量b在向量a的时针方向!
判断顺时针
有了上面的铺垫,想必大家一目了然,也就是向量外积模小于0,θ>180°的时候向量b在向量a的顺时针方向!
图示
正下方
正下方情况也就是θ=180°的时候,这个时候外积|a|x|b|sinθ=0,并且正上方的θ=0°,外积也为0。
如何判断在θ=0°,是在正上方还是正下方呢?
我们引入向量的另一个知识内积,内积公式为a·b=|a|x|b|cosθ,
当θ=180°时,cosθ=-1,当θ=0°时cosθ=1,所以如果为与正下方向量的内积应该小于0!
正上方
那么位于正上方是不是内积大于0呢?
答案是否定的!!!
为什么呢?
我们看最后一种情况,点位于线段内的情况,这种情况的内积也满足θ=0°,内积>0所以无法判断是在正上方!!!
究竟如何判定呢?
其实非常简单,当位于正上方时,向量b的模是大于向量a的模的!也就是向量b长于向量a!
图示
我们只要对向量a、b进行取模比较长度即可!
点在线段上
点在线段上就非常简单,首先外积等于0,内积大于0,只要b的模小于a的模就可以满足点在线段上!
(代码中,只要不满足前4中情况就是点在线段上)
实现代码
#include <bits/stdc++.h>
using namespace std;
class Point
{
public:
double x,y;
Point(double x=0,double y=0):x(x),y(y) {
}
//向量大小(取模)
double abs()
{
return sqrt(norm());
}
//向量范数(模的平方)
double norm()
{
return x*x+y*y;
}
};
typedef Point Vector;
//向量内积
double dot(Vector a,Vector b)
{
return a.x*b.x+a.y*b.y;
}
//向量外积
double cross(Vector a,Vector b)
{
return a.x*b.y-a.y