废话不多说,直接进入正题:
判断某点是否在特定区域内,使用 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);
}
}
小结: 判断点是否在某个特定区域有很多种办法,常用的是 射线法 ,就是通过该点做一条水平的直线,判断该直线与特定区域的交点个数, 如果是奇数点的话,该点就在特殊区域内, 如果是偶数点的话 就不在。
图画的比较丑,大家了解意思就好!
听说 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);
}
}