KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > util > Matrix


1 /**
2  * Copyright (c) 2003, www.pdfbox.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. Neither the name of pdfbox; nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * http://www.pdfbox.org
29  *
30  */

31 package org.pdfbox.util;
32
33 import java.awt.geom.AffineTransform JavaDoc;
34
35 /**
36  * This class will be used for matrix manipulation.
37  *
38  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
39  * @version $Revision: 1.14 $
40  */

41 public class Matrix implements Cloneable JavaDoc
42 {
43     private float[] single =
44     {
45         1,0,0,
46         0,1,0,
47         0,0,1
48     };
49
50     /**
51      * Constructor.
52      */

53     public Matrix()
54     {
55         //default constructor
56
}
57     
58     /**
59      * Create an affine transform from this matrix's values.
60      *
61      * @return An affine transform with this matrix's values.
62      */

63     public AffineTransform JavaDoc createAffineTransform()
64     {
65         AffineTransform JavaDoc retval = new AffineTransform JavaDoc(
66             single[0], single[1],
67             single[3], single[4],
68             single[6], single[7] );
69         return retval;
70     }
71     
72     /**
73      * Set the values of the matrix from the AffineTransform.
74      *
75      * @param af The transform to get the values from.
76      */

77     public void setFromAffineTransform( AffineTransform JavaDoc af )
78     {
79         single[0] = (float)af.getScaleX();
80         single[1] = (float)af.getShearY();
81         single[3] = (float)af.getShearX();
82         single[4] = (float)af.getScaleY();
83         single[6] = (float)af.getTranslateX();
84         single[7] = (float)af.getTranslateY();
85     }
86
87     /**
88      * This will get a matrix value at some point.
89      *
90      * @param row The row to get the value from.
91      * @param column The column to get the value from.
92      *
93      * @return The value at the row/column position.
94      */

95     public float getValue( int row, int column )
96     {
97         return single[row*3+column];
98     }
99
100     /**
101      * This will set a value at a position.
102      *
103      * @param row The row to set the value at.
104      * @param column the column to set the value at.
105      * @param value The value to set at the position.
106      */

107     public void setValue( int row, int column, float value )
108     {
109         single[row*3+column] = value;
110     }
111     
112     /**
113      * Return a single dimension array of all values in the matrix.
114      *
115      * @return The values ot this matrix.
116      */

117     public float[][] getValues()
118     {
119         float[][] retval = new float[3][3];
120         retval[0][0] = single[0];
121         retval[0][1] = single[1];
122         retval[0][2] = single[2];
123         retval[1][0] = single[3];
124         retval[1][1] = single[4];
125         retval[1][2] = single[5];
126         retval[2][0] = single[6];
127         retval[2][1] = single[7];
128         retval[2][2] = single[8];
129         return retval;
130     }
131     
132     /**
133      * Return a single dimension array of all values in the matrix.
134      *
135      * @return The values ot this matrix.
136      */

137     public double[][] getValuesAsDouble()
138     {
139         double[][] retval = new double[3][3];
140         retval[0][0] = single[0];
141         retval[0][1] = single[1];
142         retval[0][2] = single[2];
143         retval[1][0] = single[3];
144         retval[1][1] = single[4];
145         retval[1][2] = single[5];
146         retval[2][0] = single[6];
147         retval[2][1] = single[7];
148         retval[2][2] = single[8];
149         return retval;
150     }
151
152     /**
153      * This will take the current matrix and multipy it with a matrix that is passed in.
154      *
155      * @param b The matrix to multiply by.
156      *
157      * @return The result of the two multiplied matrices.
158      */

159     public Matrix multiply( Matrix b )
160     {
161         Matrix result = new Matrix();
162
163         float[] bMatrix = b.single;
164         float[] resultMatrix = result.single;
165         resultMatrix[0] = single[0] * bMatrix[0] + single[1] * bMatrix[3] + single[2] * bMatrix[6];
166         resultMatrix[1] = single[0] * bMatrix[1] + single[1] * bMatrix[4] + single[2] * bMatrix[7];
167         resultMatrix[2] = single[0] * bMatrix[2] + single[1] * bMatrix[5] + single[2] * bMatrix[8];
168         resultMatrix[3] = single[3] * bMatrix[0] + single[4] * bMatrix[3] + single[5] * bMatrix[6];
169         resultMatrix[4] = single[3] * bMatrix[1] + single[4] * bMatrix[4] + single[5] * bMatrix[7];
170         resultMatrix[5] = single[3] * bMatrix[2] + single[4] * bMatrix[5] + single[5] * bMatrix[8];
171         resultMatrix[6] = single[6] * bMatrix[0] + single[7] * bMatrix[3] + single[8] * bMatrix[6];
172         resultMatrix[7] = single[6] * bMatrix[1] + single[7] * bMatrix[4] + single[8] * bMatrix[7];
173         resultMatrix[8] = single[6] * bMatrix[2] + single[7] * bMatrix[5] + single[8] * bMatrix[8];
174
175         return result;
176     }
177     
178     /**
179      * Create a new matrix with just the scaling operators.
180      *
181      * @return A new matrix with just the scaling operators.
182      */

183     public Matrix extractScaling()
184     {
185         Matrix retval = new Matrix();
186         
187         retval.single[0] = this.single[0];
188         retval.single[4] = this.single[4];
189         
190         return retval;
191     }
192     
193     /**
194      * Convenience method to create a scaled instance.
195      *
196      * @param x The xscale operator.
197      * @param y The yscale operator.
198      * @return A new matrix with just the x/y scaling
199      */

200     public static Matrix getScaleInstance( float x, float y)
201     {
202         Matrix retval = new Matrix();
203         
204         retval.single[0] = x;
205         retval.single[4] = y;
206         
207         return retval;
208     }
209     
210     /**
211      * Create a new matrix with just the translating operators.
212      *
213      * @return A new matrix with just the translating operators.
214      */

215     public Matrix extractTranslating()
216     {
217         Matrix retval = new Matrix();
218         
219         retval.single[6] = this.single[6];
220         retval.single[7] = this.single[7];
221         
222         return retval;
223     }
224     
225     /**
226      * Convenience method to create a translating instance.
227      *
228      * @param x The x translating operator.
229      * @param y The y translating operator.
230      * @return A new matrix with just the x/y translating.
231      */

232     public static Matrix getTranslatingInstance( float x, float y)
233     {
234         Matrix retval = new Matrix();
235         
236         retval.single[6] = x;
237         retval.single[7] = y;
238         
239         return retval;
240     }
241
242     /**
243      * Clones this object.
244      * @return cloned matrix as an object.
245      */

246     public Object JavaDoc clone()
247     {
248         Matrix clone = new Matrix();
249         System.arraycopy( single, 0, clone.single, 0, 9 );
250         return clone;
251     }
252
253     /**
254      * This will copy the text matrix data.
255      *
256      * @return a matrix that matches this one.
257      */

258     public Matrix copy()
259     {
260         return (Matrix) clone();
261     }
262
263     /**
264      * This will return a string representation of the matrix.
265      *
266      * @return The matrix as a string.
267      */

268     public String JavaDoc toString()
269     {
270         StringBuffer JavaDoc result = new StringBuffer JavaDoc( "" );
271         result.append( "[[" );
272         result.append( single[0] + "," );
273         result.append( single[1] + "," );
274         result.append( single[2] + "][");
275         result.append( single[3] + "," );
276         result.append( single[4] + "," );
277         result.append( single[5] + "][");
278         result.append( single[6] + "," );
279         result.append( single[7] + "," );
280         result.append( single[8] + "]]");
281         
282         return result.toString();
283     }
284     
285     /**
286      * Get the xscaling factor of this matrix.
287      * @return The x-scale.
288      */

289     public float getXScale()
290     {
291         float xScale = single[0];
292         
293         /**
294          * BM: if the trm is rotated, the calculation is a little more complicated
295          *
296          * The rotation matrix multiplied with the scaling matrix is:
297          * ( x 0 0) ( cos sin 0) ( x*cos x*sin 0)
298          * ( 0 y 0) * (-sin cos 0) = (-y*sin y*cos 0)
299          * ( 0 0 1) ( 0 0 1) ( 0 0 1)
300          *
301          * So, if you want to deduce x from the matrix you take
302          * M(0,0) = x*cos and M(0,1) = x*sin and use the theorem of Pythagoras
303          *
304          * sqrt(M(0,0)^2+M(0,1)^2) =
305          * sqrt(x2*cos2+x2*sin2) =
306          * sqrt(x2*(cos2+sin2)) = <- here is the trick cos2+sin2 is one
307          * sqrt(x2) =
308          * abs(x)
309          */

310         if( !(single[1]==0.0f && single[3]==0.0f) )
311         {
312             xScale = (float)Math.sqrt(Math.pow(single[0], 2)+
313                                       Math.pow(single[1], 2));
314         }
315         return xScale;
316     }
317     
318     /**
319      * Get the y scaling factor of this matrix.
320      * @return The y-scale factor.
321      */

322     public float getYScale()
323     {
324         float yScale = single[4];
325         if( !(single[1]==0.0f && single[3]==0.0f) )
326         {
327             yScale = (float)Math.sqrt(Math.pow(single[3], 2)+
328                                       Math.pow(single[4], 2));
329         }
330         return yScale;
331     }
332     
333     /**
334      * Get the x position in the matrix.
335      * @return The x-position.
336      */

337     public float getXPosition()
338     {
339         return single[6];
340     }
341     
342     /**
343      * Get the y position.
344      * @return The y position.
345      */

346     public float getYPosition()
347     {
348         return single[7];
349     }
350 }
Popular Tags