001: /*
002: * @(#)Spline2D.java
003: *
004: * Copyright (c) 2003 Martin Krueger
005: * Copyright (c) 2005 David Benson
006: *
007: */
008: package org.jgraph.util;
009:
010: import java.awt.geom.Point2D;
011:
012: /**
013: * Interpolates points given in the 2D plane. The resulting spline
014: * is a function s: R -> R^2 with parameter t in [0,1].
015: *
016: * @author krueger
017: */
018: public class Spline2D {
019:
020: /**
021: * Array representing the relative proportion of the total distance
022: * of each point in the line ( i.e. first point is 0.0, end point is
023: * 1.0, a point halfway on line is 0.5 ).
024: */
025: private double[] t;
026: private Spline splineX;
027: private Spline splineY;
028: /**
029: * Total length tracing the points on the spline
030: */
031: private double length;
032:
033: /**
034: * Creates a new Spline2D.
035: * @param points
036: */
037: public Spline2D(Point2D[] points) {
038: double[] x = new double[points.length];
039: double[] y = new double[points.length];
040:
041: for (int i = 0; i < points.length; i++) {
042: x[i] = points[i].getX();
043: y[i] = points[i].getY();
044: }
045:
046: init(x, y);
047: }
048:
049: /**
050: * Creates a new Spline2D.
051: * @param x
052: * @param y
053: */
054: public Spline2D(double[] x, double[] y) {
055: init(x, y);
056: }
057:
058: private void init(double[] x, double[] y) {
059: if (x.length != y.length) {
060: throw new IllegalArgumentException(
061: "Arrays must have the same length.");
062: }
063:
064: if (x.length < 2) {
065: throw new IllegalArgumentException(
066: "Spline edges must have at least two points.");
067: }
068:
069: t = new double[x.length];
070: t[0] = 0.0; // start point is always 0.0
071:
072: // Calculate the partial proportions of each section between each set
073: // of points and the total length of sum of all sections
074: for (int i = 1; i < t.length; i++) {
075: double lx = x[i] - x[i - 1];
076: double ly = y[i] - y[i - 1];
077: // If either diff is zero there is no point performing the square root
078: if (0.0 == lx) {
079: t[i] = Math.abs(ly);
080: } else if (0.0 == ly) {
081: t[i] = Math.abs(lx);
082: } else {
083: t[i] = Math.sqrt(lx * lx + ly * ly);
084: }
085:
086: length += t[i];
087: t[i] += t[i - 1];
088: }
089:
090: for (int i = 1; i < (t.length) - 1; i++) {
091: t[i] = t[i] / length;
092: }
093:
094: t[(t.length) - 1] = 1.0; // end point is always 1.0
095:
096: splineX = new Spline(t, x);
097: splineY = new Spline(t, y);
098: }
099:
100: /**
101: * @param t 0 <= t <= 1
102: */
103: public double[] getPoint(double t) {
104: double[] result = new double[2];
105: result[0] = splineX.getValue(t);
106: result[1] = splineY.getValue(t);
107:
108: return result;
109: }
110:
111: public double getDx(double t) {
112: return splineX.getDx(t);
113: }
114:
115: public double getDy(double t) {
116: return splineY.getDx(t);
117: }
118:
119: public double getLength() {
120: return length;
121: }
122:
123: }
|