zoukankan      html  css  js  c++  java
  • 计算几何O(logN) 判断点在凸多边形内

    二维平面内判断点是否在一个简单多边形内部,在程序设计中我们一般采用射线法,或者内角和法。

    如果这个简单多边形是一个凸多边形,可以在logN的时间复杂度内判断点是否在N个顶点的凸多边形中。

    如图 判断点P是否在凸多边形内 设凸多边形顶点保存在convex[0..n-1]中

    首先必须满足 向量convex[0]-P X convex[0]-convex[1]<0 convex[0]-P X convex[0]-convex[6]>0

    X代表叉乘 如果允许点在多边形边上 <0 >0可以改写为<=0 >=0

    这样确定点在角106范围内后   二分枚举2--6每个点x  利用叉乘可以判断向量convex[0]-P在convex[0]-convex[x]逆时针还是顺时针 如果是在逆时针 继续向x--6寻找顶点 否则在2--x-1寻找顶点 直到寻找到最接近P且在P顺时针方向的边convex[0]--convex[x]

    此时可以确定点在角x-1 o x范围内

    然后向量convex[x-1]-P X convex[x-1]-convex[x] 判断P是否在线段x-1--x的左侧 在左侧点在多边形内 否则不在

    因为任意凸多边形都可以按照其中一个顶点三角剖分 所以有了logN的二分高效算法

    /**************************************
    Author : lxglbk
    Date : 2012/08/17
    Function : To determine whether a point is inside of a convex polygon in 2D plane
    O(logN)
    *********/
    double cross(cpoint p0, cpoint p1, cpoint p2)
    {
    	return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
    }
    
    bool Compl_inside_convex(const cpoint & p,cpoint *con,int n)
    {
    	if(n<3) return false;
    	if(cross(con[0],p,con[1])>-eps) return false;
    	if(cross(con[0],p,con[n-1])<eps) return false;
    
    	int i=2,j=n-1;
    	int line=-1;
    
    	while(i<=j)
    	{
    		int mid=(i+j)>>1;
    		if(cross(con[0],p,con[mid])>-eps)
    		{
    			line=mid;
    			j=mid-1;
    		}
    		else i=mid+1;
    	}
    	return cross(con[line-1],p,con[line])<-eps;
    }
    

      

  • 相关阅读:
    大战设计模式【5】—— 工厂方法模式
    通过spring抽象路由数据源+MyBatis拦截器实现数据库自动读写分离
    大战设计模式【4】—— 简单工厂模式
    大战设计模式【3】—— 装饰模式
    大战设计模式【2】—— 观察者模式
    大战设计模式【1】—— 策略模式
    回顾:maven配置和常用命令整理
    idea properties文件unicode码问题
    Nginx学习笔记
    tomcat添加context方式部署web应用
  • 原文地址:https://www.cnblogs.com/lxglbk/p/2644805.html
Copyright © 2011-2022 走看看