判断点是否在封闭区域里面

一、判断点在不在区域里面方法

     1.判断点在不在区域里面,作点水平向左的线段(这个水平线段尽量的达到X轴负方向),看与图形(代指区域)的交点是否是奇数个,如果是奇数个就是在图形里面。 关于交点特殊情况的判断,如果水平向左的线段与图形的线段重合,则记为2个交点(或者0个),水平向左的线段与图形的线段的交点是图形线段的端点的情况,这个端点是图形线段的高点则交点加一(高点即线段两点Y轴坐标大的那个点),否则不加。

源代码如下

 

package chu.anywhere;

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

 

public class TestPP {
 //判断点在不在图形内 (此图形只能在正坐标)
  Boolean IsPointInPolygon(Point2D P,Point2D[] V)
  {
   int count=0;
   Point2D p2=new Point2D.Double(-1,P.getY());
   Line2D l2=new Line2D.Double(p2,P);
   for(int j=0;j<V.length-1;j++)
   {
   if(PinL(P,new Line2D.Double(V[j],V[j+1]))) 
   {
    return true;
   }
   }
    if(PinL(P,new Line2D.Double(V[0],V[V.length-1]))) 
   {
    return true;
   }
   for(int i=0;i<V.length-1;i++)
   {
   //如果平行就忽略
    if(llll(l2,new Line2D.Double(V[i],V[i+1])))
    {
     
    }else//如果不平行就判断线段是否相交
    {
     if(java.awt.geom.Line2D.linesIntersect(l2.getX1(),l2.getY1(),l2.getX2(),l2.getY2(),V[i].getX(),V[i].getY(),V[i+1].getX(),V[i+1].getY()))
     {
      if(p(l2,new Line2D.Double(V[i],V[i+1])))
      {
      if(high(l2,new Line2D.Double(V[i],V[i+1])))
      {
      count++;
      }
      }else{
       count++;
      }
     }
    }
   
    
   }
   if(llll(l2,new Line2D.Double(V[V.length-1],V[0])))
   {
    
   }else
   {
    if(java.awt.geom.Line2D.linesIntersect(l2.getX1(),l2.getY1(),l2.getX2(),l2.getY2(),V[V.length-1].getX(),V[V.length-1].getY(),V[0].getX(),V[0].getY()))
    {
     if(p(l2,new Line2D.Double(V[V.length-1],V[0])))
     {
     if(high(l2,new Line2D.Double(V[V.length-1],V[0])))
     {
     count++;
     }
     }else{
      count++;
     }
    }
   }
   if(count%2==1)
   {
    return true;
   }else
   {
    return false;
   }
   
   
   
  }
 //判断点在不在直线上
  public boolean PinL(Point2D p1,Line2D l1)
  {
   if(((p1.getY()-l1.getY1())*(p1.getX()-l1.getX2()))==((p1.getX()-l1.getX1())*(p1.getY()-l1.getY2()))&&(((p1.getY()<=l1.getY1())&&(p1.getY()>=l1.getY2()))||((p1.getY()>=l1.getY1())&&(p1.getY()<=l1.getY2())))&&(((p1.getX()<=l1.getX1())&&(p1.getX()>=l1.getX2()))||((p1.getX()>=l1.getX1())&&(p1.getX()<=l1.getX2()))))
   {
    return true;
   }else
   {
    return false;
   }
  }
  //判断两个线段是否平行
  public boolean llll(Line2D l1,Line2D l2)
  {
   if(((l1.getY2()-l1.getY1())*(l2.getX2()-l2.getX1()))==((l1.getX2()-l1.getX1())*(l2.getY2()-l2.getY1())))
   {
    return true;
   }
   return false;
   
  }
  public boolean high(Line2D l1,Line2D l2)
  {
   if(l2.getY1()>l2.getY2())
   {
   if(Pequals(getcrossPoint(l1.getP1(),l1.getP2(),l2.getP1(),l2.getP2()),l2.getP1()))
   {
    return true;
   }
    
   }
   if(l2.getY1()<l2.getY2())
   {
   if(Pequals(getcrossPoint(l1.getP1(),l1.getP2(),l2.getP1(),l2.getP2()),l2.getP2()))
   {
    return true;
   }
    
   }
   
   return false;
   
  }
  //判断两个直线相交是不是端点
  public boolean p(Line2D l1,Line2D l2)
  {
   if(Pequals(getcrossPoint(l1.getP1(),l1.getP2(),l2.getP1(),l2.getP2()),l2.getP1()))
   {
    return true;
   }
   
   if(Pequals(getcrossPoint(l1.getP1(),l1.getP2(),l2.getP1(),l2.getP2()),l2.getP2()))
   {
    return true;
   }
   return false;
   
  }
  //返回两个线段的交点
  public  Point2D getcrossPoint(Point2D p1,Point2D p2,Point2D q1,Point2D q2)
  {   double crossPointy;
   double tempLeft=(q2.getX()-q1.getX())*(p1.getY()-p2.getY())-(p2.getX()-p1.getX())*(q1.getY()-q2.getY());
   double temRight=(p1.getY()-q1.getY())*(p2.getX()-p1.getX())*(q2.getX()-q1.getX())+
   q1.getX()*(q2.getY()-q1.getY())*(p2.getX()-p1.getX())-p1.getX()*(p2.getY()-p1.getY())*(q2.getX()-q1.getX());
   double crossPointx;
   if(Pequals(p1,q1))
   {
    return p1;
   }
   if(Pequals(p1,q2))
   {
    return p1;
   }
   if(Pequals(p2,q1))
   {
    return p2;
   }
   if(Pequals(p2,q2))
   {
    return p2;
   }
   
   if(tempLeft==0)
   {
    if(LPequals(p1,new Line2D.Double(q1,q2)))
    {
     return p1;
    }else if(LPequals(p2,new Line2D.Double(q1,q2)))
    {
     return p2;
    }
    else
    {
     return null;
    }
   }else
   {
    crossPointx=temRight/tempLeft;
   }
   if(p2.getX()-p1.getX()==0)
   {
    crossPointy=q1.getY();
   }
   else{
    crossPointy=(p2.getY()-p1.getY())/(p2.getX()-p1.getX())*(crossPointx-p1.getX())+p1.getY();
   }
    
   Point2D crossPoint=new Point2D.Double.Double(crossPointx,crossPointy);
   return crossPoint;
 }
  //判断点是不是直线的端点
  public boolean LPequals(Point2D p1,Line2D line2D)
  {
   if(Pequals(p1,line2D.getP1()))
   {
    return true;
   }else if(Pequals(p1,line2D.getP2()))
   {
    return true;
   }else{
    return false;
   }
  }
  //判断两点是否重合
  public  boolean Pequals(Point2D point,Point2D anotherPoint)
  {
   if(point.getX()==anotherPoint.getX()&&point.getY()==anotherPoint.getY())
   {
    return true;
   }
   return false;
  }
  public static void main(String[] args) {
   TestPP l3=new TestPP();
   //构造一个由(110,110),(150,150),(110,130),(150,130)围城的封闭区域
   Point2D p1=new Point2D.Double(110,110);
   Point2D p2=new Point2D.Double(150,150);
   Point2D p3=new Point2D.Double(110,130);
   Point2D p4=new Point2D.Double(150,130);
   Point2D p5=new Point2D.Double(120,120);
   Point2D p6=new Point2D.Double(170,120);
    Point2D[] pszcopy=new Point2D[4];
    pszcopy[0]=p1;
    pszcopy[1]=p2;
    pszcopy[2]=p3;
    pszcopy[3]=p4;
    //判断点p5在不在区域里面
    if(l3.IsPointInPolygon(p5,pszcopy))
    {
      System.out.println("点在区域里面 ");
    }else
    {
     System.out.println("点不在区域里面 ");
    }
    //同理判断点p6在不在 区域里面
    if(l3.IsPointInPolygon(p6,pszcopy))
    {
      System.out.println("点在区域里面 ");
    }else
    {
     System.out.println("点不在区域里面 ");
    }
    
  }

}



代码可以跑起来,里面的方法有些与常规想法略有区别,那是因为这个类在运算ArcGIS网格的时候,数据比较棘手,多了一些判断,只是把情况考虑的更为清楚,对需要判断点在不在区域这个方法不影响,后续的我会发表ArcGIS网格计算的其他代码,本人代码不够优化,希望有人指出,我会一一回复的。

没有更多推荐了,返回首页