View Javadoc

1   /*
2    * jcurl java curling software framework https://JCurl.mro.name
3    * Copyright (C) 2005-2009 M. Rohrmoser
4    * 
5    * This program is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License as published by the
7    * Free Software Foundation; either version 2 of the License, or (at your
8    * option) any later version.
9    * 
10   * This program is distributed in the hope that it will be useful, but
11   * WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13   * Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License along
16   * with this program; if not, write to the Free Software Foundation, Inc.,
17   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18   */
19  package org.jcurl.math;
20  
21  import java.awt.geom.AffineTransform;
22  
23  /**
24   * Multidimensional curves of polynomes.
25   * 
26   * @author <a href="mailto:JCurl@mro.name">M. Rohrmoser </a>
27   * @version $Id: PolynomeCurve.java 1031 2009-07-23 15:06:05Z mro $
28   */
29  public class PolynomeCurve extends R1RNFunctionImpl {
30  
31  	private static final long serialVersionUID = 7503158531478359260L;
32  
33  	static double[] add(double[] p1, double[] p2, double[] ret) {
34  		// swap if dim(p1) < dim(p2):
35  		if (p1.length < p2.length) {
36  			final double[] tmp = p1;
37  			p1 = p2;
38  			p2 = tmp;
39  		}
40  		// initialise the return array:
41  		if (ret == null || ret.length < p1.length || p1 == ret || p2 == ret)
42  			ret = new double[p1.length];
43  		else if (ret.length > p1.length)
44  			for (int i = p1.length; i < ret.length; i++)
45  				ret[i] = 0;
46  		// add p1 and p2
47  		for (int i = p2.length - 1; i >= 0; i--)
48  			ret[i] = p1[i] + p2[i];
49  		for (int i = p1.length - 1; i >= p2.length; i--)
50  			ret[i] = p1[i];
51  		return ret;
52  	}
53  
54  	public static double[] mult(final double[] p1, final double[] p2,
55  			double[] ret) {
56  		// initialise the return array:
57  		if (ret == null || ret.length < p1.length + p2.length || p1 == ret
58  				|| p2 == ret)
59  			ret = new double[p1.length + p2.length - 1];
60  		for (int i = ret.length - 1; i >= 0; i--)
61  			ret[i] = 0;
62  		for (int j = p1.length - 1; j >= 0; j--)
63  			for (int k = p2.length - 1; k >= 0; k--)
64  				ret[j + k] += p1[j] * p2[k];
65  		return ret;
66  	}
67  
68  	/**
69  	 * Works only proper for 2 Dimensions!
70  	 * 
71  	 * @param at
72  	 * @param p
73  	 * @return the transformed curve.
74  	 */
75  	public static PolynomeCurve transform(final AffineTransform at,
76  			final PolynomeCurve p) {
77  		final double[][] ret = new double[p.params.length][];
78  		for (int i = ret.length - 1; i >= 2; i--)
79  			ret[i] = p.params[i]; // clone? No: immutable
80  		final double m00 = at.getScaleX();
81  		final double m10 = at.getShearY();
82  		final double m01 = at.getShearX();
83  		final double m11 = at.getScaleY();
84  		final double m02 = at.getTranslateX();
85  		final double m12 = at.getTranslateY();
86  		double[] tmp = null;
87  		ret[0] = MathVec.mult(m00, p.params[0], ret[0]);
88  		tmp = MathVec.mult(m01, p.params[1], tmp);
89  		ret[0] = PolynomeCurve.add(ret[0], tmp, ret[0]);
90  		ret[0][0] += m02;
91  
92  		ret[1] = MathVec.mult(m10, p.params[0], ret[1]);
93  		tmp = MathVec.mult(m11, p.params[1], tmp);
94  		ret[1] = PolynomeCurve.add(ret[1], tmp, ret[1]);
95  		ret[1][0] += m12;
96  
97  		return new PolynomeCurve(ret);
98  	}
99  
100 	private final double[][] params;
101 
102 	public PolynomeCurve(final double[][] params) {
103 		super(params.length);
104 		this.params = params;
105 	}
106 
107 	public PolynomeCurve(final Polynome[] polys) {
108 		super(polys.length);
109 		params = new double[polys.length][];
110 		for (int i = params.length - 1; i >= 0; i--)
111 			params[i] = polys[i].params;
112 	}
113 
114 	@Override
115 	public double at(final double t, final int c, final int dim) {
116 		return Polynome.poly(t, c, params[dim]);
117 	}
118 
119 	@Override
120 	public String toString() {
121 		final StringBuilder b = new StringBuilder();
122 		b.append("[");
123 		for (final double[] element : params)
124 			b.append(Polynome.toString(element)).append(", ");
125 		if (params.length > 0)
126 			b.setLength(b.length() - 2);
127 		return b.toString();
128 	}
129 
130 }