001: /*
002: * Copyright (c) 2005 David Benson
003: *
004: * See LICENSE file in distribution for licensing details of this source file
005: */
006: package org.jgraph.util;
007:
008: import java.awt.Point;
009: import java.awt.geom.Point2D;
010:
011: /**
012: * Interpolates given points by a bezier curve. The first
013: * and the last two points are interpolated by a quadratic
014: * bezier curve; the other points by a cubic bezier curve.
015: *
016: * Let p a list of given points and b the calculated bezier points,
017: * then one get the whole curve by:
018: *
019: * sharedPath.moveTo(p[0])
020: * sharedPath.quadTo(b[0].x, b[0].getY(), p[1].x, p[1].getY());
021: *
022: * for(int i = 2; i < p.length - 1; i++ ) {
023: * Point b0 = b[2*i-3];
024: * Point b1 = b[2*i-2];
025: * sharedPath.curveTo(b0.x, b0.getY(), b1.x, b1.getY(), p[i].x, p[i].getY());
026: * }
027: *
028: * sharedPath.quadTo(b[b.length-1].x, b[b.length-1].getY(), p[n - 1].x, p[n - 1].getY());
029: *
030: * @author krueger
031: */
032: public class Bezier {
033:
034: private static final float AP = 0.5f;
035: private Point2D[] bPoints;
036:
037: /**
038: * Creates a new Bezier curve.
039: * @param points
040: */
041: public Bezier(Point2D[] points) {
042: int n = points.length;
043: if (n < 3) {
044: // Cannot create bezier with less than 3 points
045: return;
046: }
047: bPoints = new Point[2 * (n - 2)];
048: double paX, paY;
049: double pbX = points[0].getX();
050: double pbY = points[0].getY();
051: double pcX = points[1].getX();
052: double pcY = points[1].getY();
053: for (int i = 0; i < n - 2; i++) {
054: paX = pbX;
055: paY = pbY;
056: pbX = pcX;
057: pbY = pcY;
058: pcX = points[i + 2].getX();
059: pcY = points[i + 2].getY();
060: double abX = pbX - paX;
061: double abY = pbY - paY;
062: double acX = pcX - paX;
063: double acY = pcY - paY;
064: double lac = Math.sqrt(acX * acX + acY * acY);
065: acX = acX / lac;
066: acY = acY / lac;
067:
068: double proj = abX * acX + abY * acY;
069: proj = proj < 0 ? -proj : proj;
070: double apX = proj * acX;
071: double apY = proj * acY;
072:
073: double p1X = pbX - AP * apX;
074: double p1Y = pbY - AP * apY;
075: bPoints[2 * i] = new Point((int) p1X, (int) p1Y);
076:
077: acX = -acX;
078: acY = -acY;
079: double cbX = pbX - pcX;
080: double cbY = pbY - pcY;
081: proj = cbX * acX + cbY * acY;
082: proj = proj < 0 ? -proj : proj;
083: apX = proj * acX;
084: apY = proj * acY;
085:
086: double p2X = pbX - AP * apX;
087: double p2Y = pbY - AP * apY;
088: bPoints[2 * i + 1] = new Point((int) p2X, (int) p2Y);
089: }
090: }
091:
092: /**
093: * Returns the calculated bezier points.
094: * @return the calculated bezier points
095: */
096: public Point2D[] getPoints() {
097: return bPoints;
098: }
099:
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: }
|