001/* 002 * $Id: Matrix.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Kevin Day, Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf.parser; 045 046import java.util.Arrays; 047 048/** 049 * Keeps all the values of a 3 by 3 matrix 050 * and allows you to do some math with matrices. 051 * 052 * @since 2.1.4 053 */ 054public class Matrix { 055 /** the row=1, col=1 position ('a') in the matrix. */ 056 public static final int I11 = 0; 057 /** the row=1, col=2 position ('b') in the matrix. */ 058 public static final int I12 = 1; 059 /** the row=1, col=3 position (always 0 for 2-D) in the matrix. */ 060 public static final int I13 = 2; 061 /** the row=2, col=1 position ('c') in the matrix. */ 062 public static final int I21 = 3; 063 /** the row=2, col=2 position ('d') in the matrix. */ 064 public static final int I22 = 4; 065 /** the row=2, col=3 position (always 0 for 2-D) in the matrix. */ 066 public static final int I23 = 5; 067 /** the row=3, col=1 ('e', or X translation) position in the matrix. */ 068 public static final int I31 = 6; 069 /** the row=3, col=2 ('f', or Y translation) position in the matrix. */ 070 public static final int I32 = 7; 071 /** the row=3, col=3 position (always 1 for 2-D) in the matrix. */ 072 public static final int I33 = 8; 073 074 /** the values inside the matrix (the identity matrix by default). 075 * <p>For reference, the indeces are as follows:<p> 076 * I11 I12 I13<p> 077 * I21 I22 I23<p> 078 * I31 I32 I33<p> 079 */ 080 private final float[] vals = new float[]{ 081 1,0,0, 082 0,1,0, 083 0,0,1 084 }; 085 086 /** 087 * constructs a new Matrix with identity. 088 */ 089 public Matrix() { 090 } 091 092 /** 093 * Constructs a matrix that represents translation 094 * @param tx 095 * @param ty 096 */ 097 public Matrix(float tx, float ty){ 098 vals[I31] = tx; 099 vals[I32] = ty; 100 } 101 102 /** 103 * Creates a Matrix with 6 specified entries 104 * @param a 105 * @param b 106 * @param c 107 * @param d 108 * @param e 109 * @param f 110 */ 111 public Matrix(float a, float b, float c, float d, float e, float f){ 112 vals[I11] = a; 113 vals[I12] = b; 114 vals[I13] = 0; 115 vals[I21] = c; 116 vals[I22] = d; 117 vals[I23] = 0; 118 vals[I31] = e; 119 vals[I32] = f; 120 vals[I33] = 1; 121 } 122 123 /** 124 * Gets a specific value inside the matrix. 125 * 126 * <p>For reference, the indeces are as follows:<p> 127 * I11 I12 I13<p> 128 * I21 I22 I23<p> 129 * I31 I32 I33<p> 130 * 131 * @param index an array index corresponding with a value inside the matrix 132 * @return the value at that specific position. 133 */ 134 public float get(int index){ 135 return vals[index]; 136 } 137 138 /** 139 * multiplies this matrix by 'b' and returns the result 140 * See http://en.wikipedia.org/wiki/Matrix_multiplication 141 * @param by The matrix to multiply by 142 * @return the resulting matrix 143 */ 144 public Matrix multiply(Matrix by){ 145 Matrix rslt = new Matrix(); 146 147 float[] a = vals; 148 float[] b = by.vals; 149 float[] c = rslt.vals; 150 151 c[I11] = a[I11]*b[I11] + a[I12]*b[I21] + a[I13]*b[I31]; 152 c[I12] = a[I11]*b[I12] + a[I12]*b[I22] + a[I13]*b[I32]; 153 c[I13] = a[I11]*b[I13] + a[I12]*b[I23] + a[I13]*b[I33]; 154 c[I21] = a[I21]*b[I11] + a[I22]*b[I21] + a[I23]*b[I31]; 155 c[I22] = a[I21]*b[I12] + a[I22]*b[I22] + a[I23]*b[I32]; 156 c[I23] = a[I21]*b[I13] + a[I22]*b[I23] + a[I23]*b[I33]; 157 c[I31] = a[I31]*b[I11] + a[I32]*b[I21] + a[I33]*b[I31]; 158 c[I32] = a[I31]*b[I12] + a[I32]*b[I22] + a[I33]*b[I32]; 159 c[I33] = a[I31]*b[I13] + a[I32]*b[I23] + a[I33]*b[I33]; 160 161 return rslt; 162 } 163 164 /** 165 * Subtracts a matrix from this matrix and returns the results 166 * @param arg the matrix to subtract from this matrix 167 * @return a Matrix object 168 */ 169 public Matrix subtract(Matrix arg){ 170 Matrix rslt = new Matrix(); 171 172 float[] a = vals; 173 float[] b = arg.vals; 174 float[] c = rslt.vals; 175 176 c[I11] = a[I11]-b[I11]; 177 c[I12] = a[I12]-b[I12]; 178 c[I13] = a[I13]-b[I13]; 179 c[I21] = a[I21]-b[I21]; 180 c[I22] = a[I22]-b[I22]; 181 c[I23] = a[I23]-b[I23]; 182 c[I31] = a[I31]-b[I31]; 183 c[I32] = a[I32]-b[I32]; 184 c[I33] = a[I33]-b[I33]; 185 186 return rslt; 187 } 188 189 /** 190 * Computes the determinant of the matrix. 191 * @return the determinant of the matrix 192 * @since 5.0.3 193 */ 194 public float getDeterminant(){ 195 // ref http://en.wikipedia.org/wiki/Determinant 196 // note that in PDF, I13 and I23 are always 0 and I33 is always 1 197 // so this could be simplified/faster 198 return vals[I11] * vals[I22] * vals[I33] 199 + vals[I12] * vals[I23] * vals[I31] 200 + vals[I13] * vals[I21] * vals[I32] 201 - vals[I11] * vals[I23] * vals[I32] 202 - vals[I12] * vals[I21] * vals[I33] 203 - vals[I13] * vals[I22] * vals[I31]; 204 } 205 206 /** 207 * Checks equality of matrices. 208 * @param obj the other Matrix that needs to be compared with this matrix. 209 * @return true if both matrices are equal 210 * @see java.lang.Object#equals(java.lang.Object) 211 */ 212 public boolean equals(Object obj) { 213 if (!(obj instanceof Matrix)) 214 return false; 215 216 return Arrays.equals(vals, ((Matrix)obj).vals); 217 } 218 219 /** 220 * Generates a hash code for this object. 221 * @return the hash code of this object 222 * @see java.lang.Object#hashCode() 223 */ 224 public int hashCode() { 225 //return Arrays.hashCode(vals); // JDK 5 code, replaced with the following 226 227 int result = 1; 228 for (int i = 0; i < vals.length; i++) 229 result = 31 * result + Float.floatToIntBits(vals[i]); 230 231 return result; 232 } 233 234 /** 235 * Generates a String representation of the matrix. 236 * @return the values, delimited with tabs and newlines. 237 * @see java.lang.Object#toString() 238 */ 239 public String toString() { 240 return vals[I11] + "\t" + vals[I12] + "\t" + vals[I13] + "\n" + 241 vals[I21] + "\t" + vals[I22] + "\t" + vals[I13] + "\n" + 242 vals[I31] + "\t" + vals[I32] + "\t" + vals[I33]; 243 } 244}