您的当前位置:首页>关注 > 正文

【技术】如何判定一个点是否在三角形内?判定方法介绍

来源:CSDN 时间:2023-04-18 09:57:26


(相关资料图)

判定一个点是否在三角形内如何判定一个点P是否存在于指定的三角形ABC内,这肯定是一个简单的问题,本文仅用一个图形界面程序展示了该问题,有兴趣的朋友可以看看。(2008.07.24最后更新) 在此处使用一种常见且简便的方法:如果三角形PAB,PAC和PBC的面积之和与三角形ABC的面积相等,即可判定点P在三角形ABC内(包括在三条边上)。 可知,该方法的关键在于如何计算三角形的面积。幸运地是,当知道三角形顶点(A,B和C)的坐标((Ax, Ay),(Bx, By)和(Cx, Cy))之后,即可计算出其面积: S  = |(Ax * By + Bx * Cy + Cx * Zy - Ay * Bx - By * Cx - Cy * Ax) /  2| 关键的代码如下, //  由给定的三个顶点的坐标,计算三角形面积。 //  Point(java.awt.Point)代表点的坐标。 private   static   double  triangleArea(Point pos1, Point pos2, Point pos3) {double  result  =  Math.abs((pos1.x  *  pos2.y  +  pos2.x  *  pos3.y  +  pos3.x  *  pos1.y              -  pos2.x  *  pos1.y  -  pos3.x  *  pos2.y  -  pos1.x  *  pos3.y)  /   2.0D );      return  result; } //  判断点pos是否在指定的三角形内。 private   static   boolean  inTriangle(Point pos, Point posA, Point posB,         Point posC) {double  triangleArea  =  triangleArea(posA, posB, posC);      double  area  =  triangleArea(pos, posA, posB);     area  +=  triangleArea(pos, posA, posC);     area  +=  triangleArea(pos, posB, posC);      double  epsilon  =   0.0001 ;   //  由于浮点数的计算存在着误差,故指定一个足够小的数,用于判定两个面积是否(近似)相等。      if  (Math.abs(triangleArea  -  area)  <  epsilon) {return   true ;     }      return   false ; } 执行该应用程序,用鼠标在其中点击三次,即可绘制一个三角形,如下组图所示: 然后仅需移动鼠标,就会出现一个空心圆圈。如果圆圈的中心在三角内(包含在三条边上),则圆圈显示为红色;否则,显示为蓝色。如下组图所示: 完整代码如下: public   class  CanvasPanel  extends  JPanel {private   static   final   long  serialVersionUID  =   - 6665936180725885346L ;      private  Point firstPoint  =   null ;      private  Point secondPoint  =   null ;      private  Point thirdPoint  =   null ;      public  CanvasPanel() {setBackground(Color.WHITE);         addMouseListener(mouseAdapter);         addMouseMotionListener(mouseAdapter);     }      public   void  paintComponent(Graphics g) {super .paintComponent(g);         drawTriangel(g);     }      private   void  drawTriangel(Graphics g) {if  (firstPoint  !=   null   &&  secondPoint  !=   null ) {g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);              if  (thirdPoint  !=   null ) {g.drawLine(firstPoint.x, firstPoint.y, thirdPoint.x, thirdPoint.y);                 g.drawLine(secondPoint.x, secondPoint.y, thirdPoint.x, thirdPoint.y);             }         }     }      private   static   boolean  inTriangle(Point pos, Point posA, Point posB,             Point posC) {double  triangeArea  =  triangleArea(posA, posB, posC);          double  area  =  triangleArea(pos, posA, posB);         area  +=  triangleArea(pos, posA, posC);         area  +=  triangleArea(pos, posB, posC);          double  epsilon  =   0.0001 ;          if  (Math.abs(triangeArea  -  area)  <  epsilon) {return   true ;         }          return   false ;     }      private   static   double  triangleArea(Point pos1, Point pos2, Point pos3) {double  result  =  Math.abs((pos1.x  *  pos2.y  +  pos2.x  *  pos3.y  +  pos3.x  *  pos1.y                             -  pos2.x  *  pos1.y  -  pos3.x  *  pos2.y  -  pos1.x  *  pos3.y)  /   2.0D );          return  result;     }      private  MouseInputAdapter mouseAdapter  =   new  MouseInputAdapter() {public   void  mouseReleased(MouseEvent e) {Point pos  =  e.getPoint();              if  (firstPoint  ==   null ) {firstPoint  =  pos;             }  else   if  (secondPoint  ==   null ) {secondPoint  =  pos;                 Graphics g  =  CanvasPanel. this .getGraphics();                 CanvasPanel. this .paintComponent(g);                 g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);             }  else   if  (thirdPoint  ==   null ) {thirdPoint  =  pos;                 Graphics g  =  CanvasPanel. this .getGraphics();                 CanvasPanel. this .paintComponent(g);                 g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);                 g.drawLine(firstPoint.x, firstPoint.y, thirdPoint.x, thirdPoint.y);                 g.drawLine(secondPoint.x, secondPoint.y, thirdPoint.x, thirdPoint.y);             }         }          public   void  mouseMoved(MouseEvent e) {Point pos  =  e.getPoint();             Graphics2D g2  =  (Graphics2D) CanvasPanel. this .getGraphics();             CanvasPanel. this .paintComponent(g2);              if  (firstPoint  !=   null   &&  secondPoint  ==   null ) {g2.drawLine(firstPoint.x, firstPoint.y, pos.x, pos.y);             }  else   if  (firstPoint  !=   null   &&  secondPoint  !=   null &&  thirdPoint  ==   null ) {g2.drawLine(firstPoint.x, firstPoint.y, pos.x, pos.y);                 g2.drawLine(secondPoint.x, secondPoint.y, pos.x, pos.y);             }  else   if  (firstPoint  !=   null   &&  secondPoint  !=   null &&  thirdPoint  !=   null ) {if  (inTriangle(pos, firstPoint, secondPoint, thirdPoint)) {g2.setColor(Color.RED);                 }  else  {g2.setColor(Color.BLUE);                 }                  int  radius  =   4 ;                 g2.drawOval(pos.x  -  radius, pos.y  -  radius, radius  *   2 , radius  *   2 );             }         }     }; } public   class  Triangle  extends  JFrame {private   static   final   long  serialVersionUID  =   1L ;      private  CanvasPanel mainPanel  =   null ;      public  Triangle() {setTitle( " Triangle " );         setSize( new  Dimension( 300 ,  200 ));         setResizable( false );         init();         Container container  =  getContentPane();         container.add(mainPanel);         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         setVisible( true );     }      private   void  init() {mainPanel  =   new  CanvasPanel();     }      public   static   void  main(String[] args) {new  Triangle();     } }

还可参见一篇英文文章:   http://www.blackpawn.com/texts/pointinpoly/default.html         好文章  ;-)

标签:

最新新闻:

新闻放送
Top