大家刚接触Java图形编程的可能对 二次曲线、贝尔曲线 的几个控制点有点迷惑,我下面有段示例方便大家理解这两个曲线的几个控制点的作用:package test.draw;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 方便理解Quadratic/Bezier曲线的几个控制点作用
*
* @author h_Davy [dave3068 AT gmail DOT com]
* @version 2007-11-27 上午01:41:23
*/
public class CurvesTest extends JPanel
implements MouseListener, MouseMotionListener, FocusListener {
private static final long serialVersionUID = 1L;
public CurvesTest() {
super(true);
init();
}
private void init() {
setBackground(Color.white);
setFocusable(true);
addFocusListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
// 二次曲线
private QuadCurve q = new QuadCurve(new Point(50, 100),
new Point(200, 150), new Point(300, 100));
// 贝尔曲线
private BezierCurve b = new BezierCurve(
new Point(100, 300), new Point(200, 400),
new Point(300, 200), new Point(400, 300));
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(2.f));
// draw background
g2.setColor(getBackground());
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setColor(Color.blue);
g2.drawRect(5, 5, getWidth()-10, getHeight()-10);
// draw curves
g2.draw(q.getPath());
g2.draw(b.getPath());
// fill path area
g2.setColor(Color.lightGray);
g2.fill(q.getPath());
g2.fill(b.getPath());
// paint drag handles
g2.setColor(Color.orange);
DragHandle []dhs = q.getDragHandles();
for (int i = 0; i<dhs.length; i++)
g2.fill(dhs[i]);
dhs = b.getDragHandles();
for (int i = 0; i<dhs.length; i++)
g2.fill(dhs[i]);
}
private boolean isDrag = false; // 是否在拖动控制点
private DragHandle curDrag = null; // 当前拖动中的控制点
public void mousePressed(MouseEvent e) {
// find out is mousePoint in any DragHandle
DragHandle dh = q.findDragHandle(e.getPoint());
if (dh != null) {
curDrag = dh;
isDrag = true;
return;
}
dh = b.findDragHandle(e.getPoint());
if (dh != null) {
curDrag = dh;
isDrag = true;
return;
}
}
public void mouseReleased(MouseEvent e) {
isDrag = false;
}
public void mouseDragged(MouseEvent e) {
if (isDrag) {
curDrag.setPoint(e.getPoint());
q.refresh();
b.refresh();
repaint();
}
}
public void focusLost(FocusEvent e) {
isDrag = false;
}
// 控制点区域
@SuppressWarnings("serial")
private class DragHandle extends Rectangle {
private Point pt = new Point();
DragHandle() {
width = 5;
height = 5;
}
DragHandle(Point p) {
this();
pt.x = p.x;
pt.y = p.y;
calcRect();
}
private void calcRect() {
x = pt.x - 2;
y = pt.y - 2;
}
public void setPoint(Point p) {
pt.x = p.x;
pt.y = p.y;
calcRect();
}
public Point getPoint() {
return pt;
}
}
// Quadratic 曲线
private class QuadCurve {
// 曲线路径
protected GeneralPath gp = new GeneralPath();
// 曲线的几个控制点
protected DragHandle []pt = null;
protected QuadCurve () {}
QuadCurve(Point p1, Point p2, Point p3) {
pt = new DragHandle[3];
pt[0] = new DragHandle(p1);
pt[1] = new DragHandle(p2);
pt[2] = new DragHandle(p3);
refresh();
}
// 更新曲线
public void refresh() {
gp.reset();
gp.moveTo((float) pt[0].getX(), (float) pt[0].getY());
gp.quadTo((float) pt[1].getX(), (float) pt[1].getY(),
(float) pt[2].getX(), (float) pt[2].getY());
}
// 指定点是否在控制点区域内
public DragHandle findDragHandle(Point p) {
for (int i = 0; i<pt.length; i++)
if (pt[i].contains(p)) return pt[i];
return null;
}
// 获得所有控制点
public DragHandle[] getDragHandles() {
return pt;
}
// 获得该曲线的Path
public GeneralPath getPath() {
return gp;
}
}
// Bezier 曲线
private class BezierCurve extends QuadCurve {
protected BezierCurve(Point p1, Point p2, Point p3) {}
BezierCurve (Point p1, Point p2, Point p3, Point p4) {
pt = new DragHandle[4];
pt[0] = new DragHandle(p1);
pt[1] = new DragHandle(p2);
pt[2] = new DragHandle(p3);
pt[3] = new DragHandle(p4);
refresh();
}
public void refresh() {
gp.reset();
gp.moveTo((float) pt[0].getX(), (float) pt[0].getY());
gp.curveTo((float) pt[1].getX(), (float) pt[1].getY(),
(float) pt[2].getX(), (float) pt[2].getY(),
(float) pt[3].getX(), (float) pt[3].getY());
}
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void focusGained(FocusEvent e) {
}
/**
* @param args
*/
public static void main(String[] args) {
JFrame f = new JFrame("拖动几个橙色的小点看看 ^_^");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(640, 480);
f.setLocationRelativeTo(null);
f.add(new CurvesTest());
f.setVisible(true);
}
}
//EOF
2007-12-03
Java2D Curves Control Point
Posted by Davy Hawk at 12/03/2007 10:53:00 AM
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment