/*******************************************************************************
* Copyright (c) 2011, 2015 itemis AG and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Wienand (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.geometry.projective;
import org.eclipse.gef.geometry.planar.Point;
/**
* The Vector3D class implements a three dimensional vector (components x, y, z)
* with its standard operations: addition and multiplication (scalar,
* dot-product, cross-product).
*
* It is used to represent planar lines and planar points which are represented
* by three dimensional planes and three dimensional lines through the origin,
* respectively.
*
* @author mwienand
*
*/
public final class Vector3D {
/**
* the x-coordinate of this {@link Vector3D}.
*/
public double x;
/**
* the y-coordinate of this {@link Vector3D}.
*/
public double y;
/**
* the homogeneous coordinate of this {@link Vector3D}.
*/
public double z;
/**
* Constructs a new {@link Vector3D} object with the given component values.
*
* @param px
* The x-coordinate of the new {@link Vector3D}.
* @param py
* The y-coordinate of the new {@link Vector3D}.
* @param pz
* The z-coordinate of the new {@link Vector3D}.
*/
public Vector3D(double px, double py, double pz) {
x = px;
y = py;
z = pz;
}
/**
* Constructs a new {@link Vector3D} from the given {@link Point}, setting z
* to 1.
*
* @param p
* The {@link Point} which determines the new {@link Vector3D}'s
* x- and y-coordinate.
*/
public Vector3D(Point p) {
this(p.x, p.y, 1);
}
@Override
public boolean equals(Object other) {
if (other instanceof Vector3D) {
Vector3D o = (Vector3D) other;
Point tmp = this.toPoint();
if (tmp == null) {
return o.toPoint() == null;
}
return tmp.equals(o.toPoint());
}
return false;
}
/**
* Returns a new {@link Vector3D} object with its components set to the sum
* of the individual x, y and z components of this {@link Vector3D} and the
* given other {@link Vector3D}.
*
* @param other
* The {@link Vector3D} which is added to this {@link Vector3D}.
* @return a new {@link Vector3D} object representing the sum of this
* {@link Vector3D} and the given other {@link Vector3D}
*/
public Vector3D getAdded(Vector3D other) {
return new Vector3D(this.x + other.x, this.y + other.y,
this.z + other.z);
}
/**
* Returns a copy of this {@link Vector3D}.
*
* @return a copy of this {@link Vector3D}
*/
public Vector3D getCopy() {
return new Vector3D(x, y, z);
}
/**
* Returns a new {@link Vector3D} object that is the cross product of this
* and the given other {@link Vector3D}.
*
* @param other
* The {@link Vector3D} to which the cross product is computed.
* @return a new {@link Vector3D} object that is the cross product of this
* and the given other {@link Vector3D}
*/
public Vector3D getCrossProduct(Vector3D other) {
return new Vector3D(this.y * other.z - this.z * other.y,
this.z * other.x - this.x * other.z,
this.x * other.y - this.y * other.x);
}
/**
* Returns the dot-product of this and the given other {@link Vector3D}.
*
* @param other
* The {@link Vector3D} to which the dot product is computed.
* @return the dot-product of this and the given other {@link Vector3D}
*/
public double getDotProduct(Vector3D other) {
return this.x * other.x + this.y * other.y + this.z * other.z;
}
/**
* Returns a new {@link Vector3D} object with its components set to the
* given ratio between this {@link Vector3D} and the given other
* {@link Vector3D}.
*
* @param other
* The other {@link Vector3D}.
* @param t
* The ratio.
* @return a new {@link Vector3D} object with its components set to the
* given ratio between this {@link Vector3D} and the given other
* {@link Vector3D}
*/
public Vector3D getRatio(Vector3D other, double t) {
return getAdded(other.getSubtracted(this).getScaled(t));
}
/**
* Returns a new {@link Vector3D} object with its components set to the x, y
* and z components of this {@link Vector3D} scaled by the given factor.
*
* @param f
* The scaling factor.
* @return a new {@link Vector3D} object with its components set to the x, y
* and z components of this {@link Vector3D} scaled by the given
* factor
*/
public Vector3D getScaled(double f) {
return new Vector3D(x * f, y * f, z * f);
}
/**
* Returns a new {@link Vector3D} object with its components set to the
* difference of the individual x, y and z components of this
* {@link Vector3D} and the given other {@link Vector3D}.
*
* @param other
* The {@link Vector3D} which is subtracted from this
* {@link Vector3D}.
* @return a new {@link Vector3D} object representing the difference of this
* {@link Vector3D} and the given other {@link Vector3D}
*/
public Vector3D getSubtracted(Vector3D other) {
return new Vector3D(this.x - other.x, this.y - other.y,
this.z - other.z);
}
@Override
public int hashCode() {
// cannot generate a good hash-code because of the imprecise
// comparisons
return 0;
}
/**
* Returns a new {@link Point} object that is represented by this
* {@link Vector3D}.
*
* @return a new {@link Point} object that is represented by this
* {@link Vector3D}
*/
public Point toPoint() {
if (this.z == 0) {
return null;
}
return new Point(this.x / this.z, this.y / this.z);
}
@Override
public String toString() {
return "Vector3D(" + x + ", " + y + ", " + z + ")";
}
}