1 /** 2 * Copyright (c) 2010, David Benson 3 */ 4 package com.mxgraph.util; 5 6 import java.util.List; 7 8 public class mxSpline 9 { 10 /** 11 * Array representing the relative proportion of the total distance 12 * of each point in the line ( i.e. first point is 0.0, end point is 13 * 1.0, a point halfway on line is 0.5 ). 14 */ 15 private double[] t; 16 17 private mxSpline1D splineX; 18 19 private mxSpline1D splineY; 20 21 /** 22 * Total length tracing the points on the spline 23 */ 24 private double length; 25 mxSpline(List<mxPoint> points)26 public mxSpline(List<mxPoint> points) 27 { 28 if (points != null) 29 { 30 double[] x = new double[points.size()]; 31 double[] y = new double[points.size()]; 32 int i = 0; 33 34 for (mxPoint point : points) 35 { 36 x[i] = point.getX(); 37 y[i++] = point.getY(); 38 } 39 40 init(x, y); 41 } 42 } 43 44 /** 45 * Creates a new mxSpline. 46 * @param x 47 * @param y 48 */ Spline2D(double[] x, double[] y)49 public void Spline2D(double[] x, double[] y) 50 { 51 init(x, y); 52 } 53 init(double[] x, double[] y)54 protected void init(double[] x, double[] y) 55 { 56 if (x.length != y.length) 57 { 58 // Arrays must have the same length 59 // TODO log something 60 return; 61 } 62 63 if (x.length < 2) 64 { 65 // Spline edges must have at least two points 66 // TODO log something 67 return; 68 } 69 70 t = new double[x.length]; 71 t[0] = 0.0; // start point is always 0.0 72 length = 0.0; 73 74 // Calculate the partial proportions of each section between each set 75 // of points and the total length of sum of all sections 76 for (int i = 1; i < t.length; i++) 77 { 78 double lx = x[i] - x[i - 1]; 79 double ly = y[i] - y[i - 1]; 80 81 // If either diff is zero there is no point performing the square root 82 if (0.0 == lx) 83 { 84 t[i] = Math.abs(ly); 85 } 86 else if (0.0 == ly) 87 { 88 t[i] = Math.abs(lx); 89 } 90 else 91 { 92 t[i] = Math.sqrt(lx * lx + ly * ly); 93 } 94 95 length += t[i]; 96 t[i] += t[i - 1]; 97 } 98 99 for (int j = 1; j < (t.length) - 1; j++) 100 { 101 t[j] = t[j] / length; 102 } 103 104 t[(t.length) - 1] = 1.0; // end point is always 1.0 105 106 splineX = new mxSpline1D(t, x); 107 splineY = new mxSpline1D(t, y); 108 } 109 110 /** 111 * @param t 0 <= t <= 1 112 */ getPoint(double t)113 public mxPoint getPoint(double t) 114 { 115 mxPoint result = new mxPoint(splineX.getValue(t), splineY.getValue(t)); 116 117 return result; 118 } 119 120 /** 121 * Used to check the correctness of this spline 122 */ checkValues()123 public boolean checkValues() 124 { 125 return (splineX.len.length > 1 && splineY.len.length > 1); 126 } 127 getDx(double t)128 public double getDx(double t) 129 { 130 return splineX.getDx(t); 131 } 132 getDy(double t)133 public double getDy(double t) 134 { 135 return splineY.getDx(t); 136 } 137 getSplineX()138 public mxSpline1D getSplineX() 139 { 140 return splineX; 141 } 142 getSplineY()143 public mxSpline1D getSplineY() 144 { 145 return splineY; 146 } 147 getLength()148 public double getLength() 149 { 150 return length; 151 } 152 } 153