Java 判断点是否在特定区域内

废话不多说,直接进入正题:
判断某点是否在特定区域内,使用 java.awt.geom.GeneralPath 类中的 contains 方法;

该类常用的构造方法:

    GeneralPath ( )   构造一个新的单精度空 GeneralPath 对象
    GeneralPath(Shape s)  根据任意 Shape 对象构造一个新 GeneralPath 对象

关于 Shape 接口 想了解的自行查找API,我这里使用 Point2D.Double 实现类来绘制多边形。
具体的代码,这是绘制多边形的:

  private boolean contains(Point2D.Double point,
                                List polygon) {

        if (null == polygon || polygon.isEmpty()) { // 不存在区域坐标点,无法绘制区域
            return false;
        } else if (polygon.size() < 3) { // 区域坐标点数小于3, 无法绘制区域
            return false;
        } else {
            GeneralPath p = new GeneralPath();
            // 获取坐标区域的第一个点
            Point2D.Double first = polygon.get(0);
            // 绘图 GeneralPath 路径的开始
            p.moveTo(first.x, first.y);
            // 第一个点已经绘制完成,remove掉
            polygon.remove(0);

            for (Point2D.Double d : polygon) {
                // 按坐标连线
                p.lineTo(d.x, d.y);
            }
            // 将区域闭合
            p.lineTo(first.x, first.y);
            // 绘图结束
            p.closePath();
            // 判断 该点是否在绘制的图形内
            return p.contains(point);
        }
    }

需要注意的是 传入的 list 这个点集必须排好序,如果这个点集是乱序的话,那么绘制出来的多边形也是乱的! 切记!

/***********************分***割***线****************************/

使用Arc2D.Double 这个实现类来绘制圆:
Arc2D 使用来描述圆弧的,通过修改起始角度来画圆。
Arc2D.Double 常用的构造方法:

Arc2D.Double() 构造一个新 OPEN 弧,并将其初始化为:位置 (0, 0)、大小 (0, 0)、角跨越 (start = 0, extent = 0)

Arc2D.Double(double x, double y, double w, double h, double start, double extent, int type) 
      构造一个新弧,并将其初始化为指定的位置、大小、角跨越和闭合类型。

     (x,y) 该圆外接正方形左上角的坐标 圆的话(圆心X-半径,圆心Y-半径)

      w,h  圆的长和高  都是直径 圆的话 w == h

      start 开始角度  圆的话 是 0 

      extent 终止角度  圆的话 是 360 

      type 三个可选值 
            Arc2D.OPEN  (开弧,弧的起点和终点 不做连接)  
            Arc2D.CHORD (弓弧,弧的起点与终点用一条直线连接) 
            Arc2D.PIE   (饼弧,连线从起点开始,经过圆心,再从圆心到终点)

实例代码:

public class Circle {

    private Arc2D.Double circle;

    public Circle(){
        circle = new Arc2D.Double();
    }

    public Circle(double x, double y, double radius) {
        // x - radius  圆的外接矩形左上角X坐标
        // y - radius  圆的外接矩形左上角Y坐标
        // radius * 2  圆的直径
        this.circle = new Arc2D.Double(x - radius, y - radius,
                radius * 2, radius * 2, 0, 360, Arc2D.OPEN);
    }

    public boolean contains(double x, double y){
        //GeneralPath 的第二个常用构造方法
        GeneralPath path = new GeneralPath(circle);

        return path.contains(x, y);
    }


}

小结: 判断点是否在某个特定区域有很多种办法,常用的是 射线法 ,就是通过该点做一条水平的直线,判断该直线与特定区域的交点个数, 如果是奇数点的话,该点就在特殊区域内, 如果是偶数点的话 就不在。
Java 判断点是否在特定区域内_第1张图片
图画的比较丑,大家了解意思就好!

听说 GeneralPath 底层就是用的这种方法!所以效率还是有保障的。

下面的代码是百度的别人的,地址我忘了,就不贴了, 通过这个代码可以看到你画的圆或者多边形(自己改)。



import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Rectangle extends JComponent {
    public Rectangle() {
        setDoubleBuffered(true);
    }

    public void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;
        Arc2D arc;
        float[] solid = { 12.0f, 0.0f };
        // 消除锯齿边缘
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        Dimension size = getSize();
        g2.setColor(Color.white);
        g2.fill(new Rectangle2D.Double(0, 0, size.width, size.height));
        // 控制线段的颜色类型
        BasicStroke bs = new BasicStroke(2.0f, BasicStroke.CAP_SQUARE,
                BasicStroke.JOIN_MITER, 1.0f, solid, 0.0f);
        g2.setStroke(bs);
        arc=new Arc2D.Double(20,40,100,150,0,60,Arc2D.PIE);
        g2.setColor(Color.orange); g2.fill(arc); g2.setColor(Color.red);
        g2.draw(arc);



         arc=new Arc2D.Double(10,200,100,100,90,180,Arc2D.CHORD);
         g2.setColor(Color.orange); g2.draw(arc);


         arc=new Arc2D.Double(0,0,200,200,0,360,Arc2D.OPEN);
         g2.setColor(Color.orange);
         g2.fill(arc);
         g2.setColor(Color.red);
         g2.draw(arc);



         arc=new Arc2D.Double(220,220,100,100,-30,-300,Arc2D.PIE);
         g2.setColor(Color.orange); g2.fill(arc); g2.setColor(Color.red);
         g2.draw(arc);


    }

    public static void main(String args[]) {
        MyWindowListener l = new MyWindowListener();
        Rectangle c = new Rectangle();

        JFrame fr = new JFrame("Test...");
        fr.addWindowListener(l);
        fr.getContentPane().add(c, BorderLayout.CENTER);
        fr.pack();
        fr.setSize(400, 400);
        fr.setLocation(400, 400);
        // fr.show();
        fr.setVisible(true);

    }

}

class MyWindowListener extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
}

你可能感兴趣的:(九阳真经)