ベジエ曲線
以下のプログラムは2次ベジェ曲線を書きます.
PicturePanel.java
package beziercurve; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.ArrayList; import java.util.List; import javax.swing.JPanel; public class PicturePanel extends JPanel implements Runnable { Thread refresh = null; List<Ball> ball; List<Ball> p; Ball bezierBall; List<Point> locusPoint; double[] vx, vy; double d; // 線分の分割数 double t; // 時刻 public PicturePanel() { if( refresh == null ) { refresh = new Thread(this); refresh.start(); } t = 0; d = 200; p = new ArrayList<Ball>(); p.add(new Ball(new Point(100, 350), 10, 0, 0, Color.black)); p.add(new Ball(new Point(300, 80), 10, 0, 0, Color.black)); p.add(new Ball(new Point(500, 400), 10, 0, 0, Color.black)); vx = new double[p.size() - 1]; vy = new double[p.size() - 1]; for( int i = 0; i < p.size() - 1; i++ ) { vx[i] = (p.get(i + 1).getCenterPoint().x - p.get(i).getCenterPoint().x) / d; vy[i] = (p.get(i + 1).getCenterPoint().y - p.get(i).getCenterPoint().y) / d; } ball = new ArrayList<Ball>(); for( int i = 0; i < p.size() - 1; i++ ) { ball.add(new Ball(p.get(i).getCenterPoint(), 15, vx[i], vy[i], Color.CYAN)); } bezierBall = new Ball(p.get(0).getCenterPoint(), 2, vx[0], vy[0], Color.BLACK); locusPoint = new ArrayList<Point>(); } @Override public void paintComponent(Graphics g) { double vx, vy; super.paintComponent(g); // 線分の描画 for( int i = 0; i < p.size() - 1; i++ ) { g.setColor(Color.BLACK); g.drawLine(p.get(i).getCenterPoint().x, p.get(i).getCenterPoint().y, p.get(i + 1).getCenterPoint().x, p.get(i + 1).getCenterPoint().y); } for( int i = 0; i < p.size() - 2; i++ ) { g.setColor(Color.red); g.drawLine(ball.get(i).getCenterPoint().x, ball.get(i).getCenterPoint().y, ball.get(i + 1).getCenterPoint().x, ball.get(i + 1).getCenterPoint().y); } // 始点・終点の描画 for( Ball elemBall : p ) { g.setColor(elemBall.getColor()); g.fillOval(elemBall.getRectangle().x, elemBall.getRectangle().y, elemBall.getRectangle().width, elemBall.getRectangle().height); } // 線分上を動く円の描画 for( int i = 0; i < p.size() - 1; i++ ) { g.setColor(ball.get(i).getColor()); g.fillOval(ball.get(i).getPoint().x, ball.get(i).getPoint().y, ball.get(i).getRectangle().width, ball.get(i).getRectangle().height); ball.get(i).Move(p.get(i), t); } vx = (ball.get(1).getCenterPoint().x - ball.get(0).getCenterPoint().x) / d; vy = (ball.get(1).getCenterPoint().y - ball.get(0).getCenterPoint().y) / d; bezierBall.setV(vx, vy); bezierBall.Move(ball.get(0), t); g.setColor(bezierBall.getColor()); g.fillOval(bezierBall.getPoint().x, bezierBall.getPoint().y, bezierBall.getRectangle().width, bezierBall.getRectangle().height); g.setColor(bezierBall.getColor()); for( Point p : locusPoint ) { g.fillOval(p.x, p.y, bezierBall.getRectangle().width, bezierBall.getRectangle().height); } if( t > d ) { t = 0; locusPoint.clear(); } else { t += 1.0; locusPoint.add(bezierBall.getPoint()); } } @Override public void run() { while( true ) { repaint(); try { if( t > d ) { Thread.sleep(300); } else { Thread.sleep(10); } } catch (Exception e) { } } } }
Ball.java
package beziercurve; import java.awt.Color; import java.awt.Point; import java.awt.Rectangle; public class Ball { private Point point; private int r; private Rectangle rectangle; private double vx, vy; private Color color; public Ball(Point point, int r, double vx, double vy, Color color) { this.point = new Point(point.x - r, point.y - r); this.r = r; this.rectangle = new Rectangle(this.point.x, this.point.y, 2 * r, 2 * r); this.vx = vx; this.vy = vy; this.color = color; } public Point getPoint() { return new Point(point); } public Point getCenterPoint() { return new Point(point.x + r, point.y + r); } public Rectangle getRectangle() { return rectangle; } public Color getColor() { return color; } public void setV(double vx, double vy) { this.vx = vx; this.vy = vy; } public void Move(Ball p1, double t) { this.point.x = p1.getCenterPoint().x - r + (int)(vx * t); this.point.y = p1.getCenterPoint().y - r + (int)(vy * t); } }
BezierCurve.java
package beziercurve; import java.awt.Color; import javax.swing.JFrame; public class BezierCurve { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setBounds(200, 200, 640, 480); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); PicturePanel panel = new PicturePanel(); panel.setBackground(Color.white); frame.getContentPane().add(panel); frame.setVisible(true); } }