001/* 002 * $Id: Vector.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 * Represents a vector (i.e. a point in space). This class is completely 050 * unrelated to the {@link java.util.Vector} class in the standard JRE. 051 * <br><br> 052 * For many PDF related operations, the z coordinate is specified as 1 053 * This is to support the coordinate transformation calculations. If it 054 * helps, just think of all PDF drawing operations as occurring in a single plane 055 * with z=1. 056 */ 057public class Vector { 058 /** index of the X coordinate */ 059 public static final int I1 = 0; 060 /** index of the Y coordinate */ 061 public static final int I2 = 1; 062 /** index of the Z coordinate */ 063 public static final int I3 = 2; 064 065 /** the values inside the vector */ 066 private final float[] vals = new float[]{ 067 0,0,0 068 }; 069 070 /** 071 * Creates a new Vector 072 * @param x the X coordinate 073 * @param y the Y coordinate 074 * @param z the Z coordinate 075 */ 076 public Vector(final float x, final float y, final float z) { 077 vals[I1] = x; 078 vals[I2] = y; 079 vals[I3] = z; 080 } 081 082 /** 083 * Gets the value from a coordinate of the vector 084 * @param index the index of the value to get (I1, I2 or I3) 085 * @return a coordinate value 086 */ 087 public float get(final int index){ 088 return vals[index]; 089 } 090 091 /** 092 * Computes the cross product of this vector and the specified matrix 093 * @param by the matrix to cross this vector with 094 * @return the result of the cross product 095 */ 096 public Vector cross(final Matrix by){ 097 098 float x = vals[I1]*by.get(Matrix.I11) + vals[I2]*by.get(Matrix.I21) + vals[I3]*by.get(Matrix.I31); 099 float y = vals[I1]*by.get(Matrix.I12) + vals[I2]*by.get(Matrix.I22) + vals[I3]*by.get(Matrix.I32); 100 float z = vals[I1]*by.get(Matrix.I13) + vals[I2]*by.get(Matrix.I23) + vals[I3]*by.get(Matrix.I33); 101 102 return new Vector(x, y, z); 103 } 104 105 /** 106 * Computes the difference between this vector and the specified vector 107 * @param v the vector to subtract from this one 108 * @return the results of the subtraction 109 */ 110 public Vector subtract(final Vector v){ 111 float x = vals[I1] - v.vals[I1]; 112 float y = vals[I2] - v.vals[I2]; 113 float z = vals[I3] - v.vals[I3]; 114 115 return new Vector(x, y, z); 116 } 117 118 /** 119 * Computes the cross product of this vector and the specified vector 120 * @param with the vector to cross this vector with 121 * @return the cross product 122 */ 123 public Vector cross(final Vector with){ 124 float x = vals[I2]*with.vals[I3] - vals[I3]*with.vals[I2]; 125 float y = vals[I3]*with.vals[I1] - vals[I1]*with.vals[I3]; 126 float z = vals[I1]*with.vals[I2] - vals[I2]*with.vals[I1]; 127 128 return new Vector(x, y, z); 129 } 130 131 /** 132 * Normalizes the vector (i.e. returns the unit vector in the same orientation as this vector) 133 * @return the unit vector 134 * @since 5.0.1 135 */ 136 public Vector normalize(){ 137 float l = this.length(); 138 float x = vals[I1]/l; 139 float y = vals[I2]/l; 140 float z = vals[I3]/l; 141 return new Vector(x, y, z); 142 } 143 144 /** 145 * Multiplies the vector by a scalar 146 * @param by the scalar to multiply by 147 * @return the result of the scalar multiplication 148 * @since 5.0.1 149 */ 150 public Vector multiply(final float by){ 151 float x = vals[I1] * by; 152 float y = vals[I2] * by; 153 float z = vals[I3] * by; 154 return new Vector(x, y, z); 155 } 156 157 /** 158 * Computes the dot product of this vector with the specified vector 159 * @param with the vector to dot product this vector with 160 * @return the dot product 161 */ 162 public float dot(final Vector with){ 163 return vals[I1]*with.vals[I1] + vals[I2]*with.vals[I2] + vals[I3]*with.vals[I3]; 164 } 165 166 /** 167 * Computes the length of this vector 168 * <br> 169 * <b>Note:</b> If you are working with raw vectors from PDF, be careful - 170 * the Z axis will generally be set to 1. If you want to compute the 171 * length of a vector, subtract it from the origin first (this will set 172 * the Z axis to 0). 173 * <br> 174 * For example: 175 * <code>aVector.subtract(originVector).length();</code> 176 * 177 * @return the length of this vector 178 */ 179 public float length(){ 180 return (float)Math.sqrt(lengthSquared()); 181 } 182 183 /** 184 * Computes the length squared of this vector. 185 * 186 * The square of the length is less expensive to compute, and is often 187 * useful without taking the square root. 188 * <br><br> 189 * <b>Note:</b> See the important note under {@link Vector#length()} 190 * 191 * @return the square of the length of the vector 192 */ 193 public float lengthSquared(){ 194 return vals[I1]*vals[I1] + vals[I2]*vals[I2] + vals[I3]*vals[I3]; 195 } 196 197 /** 198 * @see java.lang.Object#toString() 199 */ 200 @Override 201 public String toString() { 202 return vals[I1]+","+vals[I2]+","+vals[I3]; 203 } 204 /** 205 * Calculates the hashcode using the values. 206 * @since 5.0.6 207 */ 208 @Override 209 public int hashCode() { 210 final int prime = 31; 211 int result = 1; 212 result = prime * result + Arrays.hashCode(vals); 213 return result; 214 } 215 /* 216 * (non-Javadoc) 217 * @see java.lang.Object#equals(java.lang.Object) 218 */ 219 @Override 220 public boolean equals(final Object obj) { 221 if (this == obj) { 222 return true; 223 } 224 if (obj == null) { 225 return false; 226 } 227 if (getClass() != obj.getClass()) { 228 return false; 229 } 230 Vector other = (Vector) obj; 231 if (!Arrays.equals(vals, other.vals)) { 232 return false; 233 } 234 return true; 235 } 236 237}