1 /* 2 * Copyright (c) 2005 David Benson 3 * 4 * See LICENSE file in distribution for licensing details of this source file 5 */ 6 package org.jgraph.util; 7 8 import java.awt.Point; 9 import java.awt.geom.Point2D; 10 11 /** 12 * Interpolates given points by a bezier curve. The first 13 * and the last two points are interpolated by a quadratic 14 * bezier curve; the other points by a cubic bezier curve. 15 * 16 * Let p a list of given points and b the calculated bezier points, 17 * then one get the whole curve by: 18 * 19 * sharedPath.moveTo(p[0]) 20 * sharedPath.quadTo(b[0].x, b[0].getY(), p[1].x, p[1].getY()); 21 * 22 * for(int i = 2; i < p.length - 1; i++ ) { 23 * Point b0 = b[2*i-3]; 24 * Point b1 = b[2*i-2]; 25 * sharedPath.curveTo(b0.x, b0.getY(), b1.x, b1.getY(), p[i].x, p[i].getY()); 26 * } 27 * 28 * sharedPath.quadTo(b[b.length-1].x, b[b.length-1].getY(), p[n - 1].x, p[n - 1].getY()); 29 * 30 * @author krueger 31 */ 32 public class Bezier { 33 34 private static final float AP = 0.5f; 35 private Point2D[] bPoints; 36 37 /** 38 * Creates a new Bezier curve. 39 * @param points 40 */ Bezier(Point2D[] points)41 public Bezier(Point2D[] points) { 42 int n = points.length; 43 if (n < 3) { 44 // Cannot create bezier with less than 3 points 45 return; 46 } 47 bPoints = new Point[2 * (n - 2)]; 48 double paX, paY; 49 double pbX = points[0].getX(); 50 double pbY = points[0].getY(); 51 double pcX = points[1].getX(); 52 double pcY = points[1].getY(); 53 for (int i = 0; i < n - 2; i++) { 54 paX = pbX; 55 paY = pbY; 56 pbX = pcX; 57 pbY = pcY; 58 pcX = points[i + 2].getX(); 59 pcY = points[i + 2].getY(); 60 double abX = pbX - paX; 61 double abY = pbY - paY; 62 double acX = pcX - paX; 63 double acY = pcY - paY; 64 double lac = Math.sqrt(acX * acX + acY * acY); 65 acX = acX /lac; 66 acY = acY /lac; 67 68 double proj = abX * acX + abY * acY; 69 proj = proj < 0 ? -proj : proj; 70 double apX = proj * acX; 71 double apY = proj * acY; 72 73 double p1X = pbX - AP * apX; 74 double p1Y = pbY - AP * apY; 75 bPoints[2 * i] = new Point((int) p1X, (int) p1Y); 76 77 acX = -acX; 78 acY = -acY; 79 double cbX = pbX - pcX; 80 double cbY = pbY - pcY; 81 proj = cbX * acX + cbY * acY; 82 proj = proj < 0 ? -proj : proj; 83 apX = proj * acX; 84 apY = proj * acY; 85 86 double p2X = pbX - AP * apX; 87 double p2Y = pbY - AP * apY; 88 bPoints[2 * i + 1] = new Point((int) p2X, (int) p2Y); 89 } 90 } 91 92 /** 93 * Returns the calculated bezier points. 94 * @return the calculated bezier points 95 */ 96 public Point2D[] getPoints() { 97 return bPoints; 98 } 99 100 /** 101 * Returns the number of bezier points. 102 * @return number of bezier points 103 */ 104 public int getPointCount() { 105 return bPoints.length; 106 } 107 108 /** 109 * Returns the bezier points at position i. 110 * @param i 111 * @return the bezier point at position i 112 */ 113 public Point2D getPoint(int i) { 114 return bPoints[i]; 115 } 116 117 } 118