您的位置:首页 > 编程语言 > Go语言

Google Interview - 判断点是否在凸多边形内的O(logn)解法

2015-06-25 15:20 537 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/yuanhisn/article/details/84725922

补充知识:向量叉积,向量P = (x1, y1); Q = (x2, y2); P×Q = (x1*y2 - x2*y1);
叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:
若 P × Q > 0 , 则P在Q的顺时针方向。
若 P × Q < 0 , 则P在Q的逆时针方向。
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。
叉积的方向与进行叉积的两个向量都垂直,所以叉积向量即为这两个向量构成平面的法向量。

我们来考虑题目,假设凸多边形各个定点坐标按照逆时针方向存储于一个数组中,那么可以通过计算0-i与0-P两个向量之间的左右关系确定点P于某两个相邻的顶点构成的向量之间,如O-x与o-(x-1),然后看是否(x-1)-p向量位于(x-1)-x向量的逆时针方向,如果是顺时针方向则不在凸多边形内。

double multiply(Point& p1, Point& p2, Point& p0) {
return (p1.x - p0.x) * (p2.y - p0.y)*1.0 - (p1.y - p0.y) * (p2.x - p0.x)*1.0;
}
bool inConvexPolygon(vector<Point> Polygon, Point target) {
int len = Polygon.size();
if (multiply(target, Polygon[1], Polygon[0]) > 0 && multiply(target, Polygon[len - 1], Polygon[0]) < 0) {
return false;
}
int s = 1, e = len -1;
int line = -1;
while (s <= e) {
int m = s + ((e-s) >> 1);
if (multiply(target, Polygon[m], Polygon[0]) > 0) { // target在m顺时针方向
line = m; // line保存的是m逆时针方向后的第一个点
e = m -1;
} else { // target在m逆时针方向
s = m + 1;
}
}
return multiply(Polygon[line], target, Polygon[line -1]) > 0;
}

  

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: