Project

General

Profile

Download (8.15 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *     Research Group Software Construction,
11
 *     RWTH Aachen University, Germany - Contribution for Bugzilla 245182
12
 *
13
 *******************************************************************************/
14
package org.eclipse.draw2d.geometry;
15

    
16
/**
17
 * Represents a vector within 2-dimensional Euclidean space.
18
 * 
19
 * @since 3.6
20
 */
21
public class Vector {
22

    
23
	/** the X value */
24
	public double x;
25
	/** the Y value */
26
	public double y;
27

    
28
	// internal constant used for comparisons.
29
	private static final Vector NULL = new Vector(0, 0);
30

    
31
	/**
32
	 * Constructs a Vector pointed in the specified direction.
33
	 * 
34
	 * @param x
35
	 *            X value.
36
	 * @param y
37
	 *            Y value.
38
	 */
39
	public Vector(double x, double y) {
40
		this.x = x;
41
		this.y = y;
42
	}
43

    
44
	/**
45
	 * Constructs a Vector pointed in the direction specified by a Point.
46
	 * 
47
	 * @param p
48
	 *            the point
49
	 */
50
	public Vector(PrecisionPoint p) {
51
		x = p.preciseX();
52
		y = p.preciseY();
53
	}
54

    
55
	/**
56
	 * Constructs a Vector representing the direction and magnitude between to
57
	 * provided Points.
58
	 * 
59
	 * @param start
60
	 *            starting point
61
	 * @param end
62
	 *            End Point
63
	 */
64
	public Vector(PrecisionPoint start, PrecisionPoint end) {
65
		x = end.preciseX() - start.preciseX();
66
		y = end.preciseY() - start.preciseY();
67
	}
68

    
69
	/**
70
	 * Constructs a Vector representing the difference between two provided
71
	 * Vectors.
72
	 * 
73
	 * @param start
74
	 *            The start Ray
75
	 * @param end
76
	 *            The end Ray
77
	 */
78
	public Vector(Vector start, Vector end) {
79
		x = end.x - start.x;
80
		y = end.y - start.y;
81
	}
82

    
83
	/**
84
	 * Calculates the magnitude of the cross product of this Vector with
85
	 * another. Represents the amount by which two Vectors are directionally
86
	 * different. Parallel Vectors return a value of 0.
87
	 * 
88
	 * @param other
89
	 *            Vector being compared
90
	 * @return The dissimilarity
91
	 */
92
	public double getDissimilarity(Vector other) {
93
		return PrecisionGeometry.preciseAbs(getCrossProduct(other));
94
	}
95

    
96
	/**
97
	 * Calculates whether this Vector and the provided one are parallel to each
98
	 * other.
99
	 * 
100
	 * @param other
101
	 *            The Vector to test for parallelism
102
	 * @return true if this Vector and the provided one are parallel, false
103
	 *         otherwise.
104
	 */
105
	public boolean isParallelTo(Vector other) {
106
		return getDissimilarity(other) == 0;
107
	}
108

    
109
	/**
110
	 * Calculates the dot product of this Vector with another.
111
	 * 
112
	 * @param other
113
	 *            the Vector used to calculate the dot product
114
	 * @return The dot product
115
	 */
116
	public double getDotProduct(Vector other) {
117
		return PrecisionGeometry.preciseAdd(
118
				PrecisionGeometry.preciseMultiply(x, other.x),
119
				PrecisionGeometry.preciseMultiply(y, other.y));
120
	}
121

    
122
	/**
123
	 * Calculates the cross product of this Vector with another.
124
	 * 
125
	 * @param other
126
	 *            the Vector used to calculate the cross product
127
	 * @return The cross product.
128
	 */
129
	public double getCrossProduct(Vector other) {
130
		return PrecisionGeometry.preciseSubtract(
131
				PrecisionGeometry.preciseMultiply(x, other.y),
132
				PrecisionGeometry.preciseMultiply(y, other.x));
133
	}
134

    
135
	/**
136
	 * Creates a new Vector which is the sum of this Vector with another.
137
	 * 
138
	 * @param other
139
	 *            Vector to be added to this Vector
140
	 * @return a new Vector representing the sum
141
	 */
142
	public Vector getAdded(Vector other) {
143
		return new Vector(PrecisionGeometry.preciseAdd(x, other.x),
144
				PrecisionGeometry.preciseAdd(y, other.y));
145
	}
146

    
147
	/**
148
	 * Creates a new Vector which is the difference of this Vector with the
149
	 * provided Vector.
150
	 * 
151
	 * @param other
152
	 *            Vector to be subtracted from this Vector
153
	 * @return a new Vector representing the difference.
154
	 */
155
	public Vector getSubtracted(Vector other) {
156
		return new Vector(PrecisionGeometry.preciseSubtract(x, other.x),
157
				PrecisionGeometry.preciseSubtract(y, other.y));
158
	}
159

    
160
	/**
161
	 * Returns the angle (in degrees) between this Vector and the provided
162
	 * Vector.
163
	 * 
164
	 * @param other
165
	 *            Vector to calculate the angle.
166
	 * @return the angle between the two Vectors in degrees.
167
	 */
168
	public double getAngle(Vector other) {
169
		double cosAlpha = PrecisionGeometry.preciseDivide(
170
				getDotProduct(other),
171
				(PrecisionGeometry.preciseMultiply(getLength(),
172
						other.getLength())));
173
		return Math.toDegrees(Math.acos(cosAlpha));
174
	}
175

    
176
	/**
177
	 * Creates a new Vector which represents the average of this Vector with
178
	 * another.
179
	 * 
180
	 * @param other
181
	 *            Vector to calculate the average.
182
	 * @return a new Vector
183
	 */
184
	public Vector getAveraged(Vector other) {
185
		return new Vector(PrecisionGeometry.preciseDivide(
186
				PrecisionGeometry.preciseAdd(x, other.x), 2),
187
				PrecisionGeometry.preciseDivide(
188
						PrecisionGeometry.preciseAdd(y, other.y), 2));
189
	}
190

    
191
	/**
192
	 * Creates a new Vector which represents this Vector multiplied by the
193
	 * provided scalar factor.
194
	 * 
195
	 * @param factor
196
	 *            Value providing the amount to scale.
197
	 * @return a new Vector
198
	 */
199
	public Vector getMultiplied(double factor) {
200
		return new Vector(PrecisionGeometry.preciseMultiply(x, factor),
201
				PrecisionGeometry.preciseMultiply(y, factor));
202
	}
203

    
204
	/**
205
	 * Creates a new Vector which represents this Vector divided by the provided
206
	 * scalar factor.
207
	 * 
208
	 * @param factor
209
	 *            Value providing the amount to scale.
210
	 * @return a new Vector
211
	 */
212
	public Vector getDivided(double factor) {
213
		return new Vector(PrecisionGeometry.preciseDivide(x, factor),
214
				PrecisionGeometry.preciseDivide(y, factor));
215
	}
216

    
217
	/**
218
	 * Returns the orthogonal complement of this Vector, which is defined to be
219
	 * (-y, x).
220
	 * 
221
	 * @return the orthogonal complement of this Vector
222
	 */
223
	public Vector getOrthogonalComplement() {
224
		return new Vector(PrecisionGeometry.preciseNegate(y), x);
225
	}
226

    
227
	/**
228
	 * Returns the length of this Vector.
229
	 * 
230
	 * @return Length of this Vector
231
	 */
232
	public double getLength() {
233
		return Math.sqrt(getDotProduct(this));
234
	}
235

    
236
	/**
237
	 * Calculates the similarity of this Vector with another. Similarity is
238
	 * defined as the absolute value of the dotProduct(). Orthogonal vectors
239
	 * return a value of 0.
240
	 * 
241
	 * @param other
242
	 *            Vector being tested for similarity
243
	 * @return the Similarity
244
	 * @see #getDissimilarity(Vector)
245
	 */
246
	public double getSimilarity(Vector other) {
247
		return PrecisionGeometry.preciseAbs(getDotProduct(other));
248
	}
249

    
250
	/**
251
	 * Calculates whether this Vector and the provided one are orthogonal to
252
	 * each other.
253
	 * 
254
	 * @param other
255
	 *            Vector being tested for orthogonality
256
	 * @return true, if this Vector and the provide one are orthogonal, false
257
	 *         otherwise
258
	 */
259
	public boolean isOrthogonalTo(Vector other) {
260
		return getSimilarity(other) == 0;
261
	}
262

    
263
	/**
264
	 * Checks whether this vector has a horizontal component.
265
	 * 
266
	 * @return true if x != 0, false otherwise.
267
	 */
268
	public boolean isHorizontal() {
269
		return x != 0;
270
	}
271

    
272
	/**
273
	 * Checks whether this vector has a vertical component.
274
	 * 
275
	 * @return true if y != 0, false otherwise.
276
	 */
277
	public boolean isVertical() {
278
		return y != 0;
279
	}
280

    
281
	/**
282
	 * Checks whether this vector equals (0,0);
283
	 * 
284
	 * @return true if x == 0 and y == 0.
285
	 */
286
	public boolean isNull() {
287
		return equals(NULL);
288
	}
289

    
290
	/**
291
	 * Returns a point representation of this Vector.
292
	 * 
293
	 * @return a PrecisionPoint representation
294
	 */
295
	public PrecisionPoint toPoint() {
296
		return new PrecisionPoint(x, y);
297
	}
298

    
299
	/**
300
	 * @see java.lang.Object#toString()
301
	 */
302
	public String toString() {
303
		return "(" + x + "," + y + ")";//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
304
	}
305

    
306
	/**
307
	 * @see java.lang.Object#equals(Object)
308
	 */
309
	public boolean equals(Object obj) {
310
		if (obj == this)
311
			return true;
312
		if (obj instanceof Vector) {
313
			Vector r = (Vector) obj;
314
			return x == r.x && y == r.y;
315
		}
316
		return false;
317
	}
318

    
319
	/**
320
	 * @see java.lang.Object#hashCode()
321
	 */
322
	public int hashCode() {
323
		return (int) x + (int) y;
324
	}
325

    
326
}
(16-16/17)