/*
* $Id$
*
* Copyright (C) 2011 Janus Core Developers
* Copyright (C) 2012 Stephane GALLAND.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* This program is free software; you can redistribute it and/or modify
*/
package org.arakhne.afc.math.geometry.d3.discrete;
import org.arakhne.afc.math.MathUtil;
import org.arakhne.afc.math.geometry.d3.Point3D;
import org.arakhne.afc.math.geometry.d3.Tuple3D;
import org.arakhne.afc.math.geometry.d3.Vector3D;
import org.arakhne.afc.math.geometry.d3.continuous.Quaternion;
import org.arakhne.afc.math.geometry.d3.continuous.Transform3D;
import org.eclipse.xtext.xbase.lib.Pure;
/** 3D Vector with 3 integers.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
public class Vector3i extends Tuple3i<Vector3D> implements Vector3D {
private static final long serialVersionUID = 1997599488590527335L;
/**
*/
public Vector3i() {
//
}
/**
* @param tuple is the tuple to copy.
*/
public Vector3i(Tuple3D<?> tuple) {
super(tuple);
}
/**
* @param tuple is the tuple to copy.
*/
public Vector3i(int[] tuple) {
super(tuple);
}
/**
* @param tuple is the tuple to copy.
*/
public Vector3i(double[] tuple) {
super(tuple);
}
/**
* @param x
* @param y
* @param z
*/
@SuppressWarnings("hiding")
public Vector3i(int x, int y, int z) {
super(x,y,z);
}
/**
* @param x
* @param y
* @param z
*/
@SuppressWarnings("hiding")
public Vector3i(float x, float y, float z) {
super(x,y,z);
}
/**
* @param x
* @param y
* @param z
*/
@SuppressWarnings("hiding")
public Vector3i(double x, double y, double z) {
super(x,y,z);
}
/**
* @param x
* @param y
* @param z
*/
@SuppressWarnings("hiding")
public Vector3i(long x, long y, long z) {
super(x,y,z);
}
/** {@inheritDoc}
*/
@Pure
@Override
public Vector3i clone() {
return (Vector3i)super.clone();
}
/**
* {@inheritDoc}
*/
@Pure
@Override
public double angle(Vector3D v1) {
double vDot = dot(v1) / ( length()*v1.length() );
if( vDot < -1.) vDot = -1.;
if( vDot > 1.) vDot = 1.;
return((Math.acos( vDot )));
}
/**
* {@inheritDoc}
*/
@Pure
@Override
public double dot(Vector3D v1) {
return (this.x*v1.getX() + this.y*v1.getY() + this.z*v1.getZ());
}
@Pure
@Override
public double perp(Vector3D v) {
/* First method:
*
* det(A,B) = |A|.|B|.sin(theta)
* A x B = |A|.|B|.sin(theta).N, where N is the unit vector
* A x B = det(A,B).N
* A x B = [ y1*z2 - z1*y2 ] = det(A,B).N
* [ z1*x2 - x1*z2 ]
* [ x1*y2 - y1*x2 ]
* det(A,B) = sum(A x B)
*
* Second method:
*
* det(A,B) = det( [ x1 x2 1 ]
* [ y1 y2 1 ]
* [ z1 z2 1 ] )
* det(A,B) = x1*y2*1 + y1*z2*1 + z1*x2*1 - 1*y2*z1 - 1*z2*x1 - 1*x2*y1
*/
return getX()*v.getY() + getY()*v.getZ() + getZ()*v.getX() - v.getY()*getZ() - v.getZ()*getX() - v.getX()*getY();
}
/**
* {@inheritDoc}
*/
@Pure
@Override
public double length() {
return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
}
/**
* {@inheritDoc}
*/
@Pure
@Override
public double lengthSquared() {
return (this.x*this.x + this.y*this.y + this.z*this.z);
}
/**
* {@inheritDoc}
*/
@Override
public void normalize(Vector3D v1) {
double norm;
norm = 1./Math.sqrt(v1.getX()*v1.getX() + v1.getY()*v1.getY() + v1.getZ()*v1.getZ());
this.x = (int)(v1.getX()*norm);
this.y = (int)(v1.getY()*norm);
this.z = (int)(v1.getZ()*norm);
}
/**
* {@inheritDoc}
*/
@Override
public void normalize() {
double norm;
norm = 1./Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
this.x *= norm;
this.y *= norm;
this.z *= norm;
}
@Override
public void add(Vector3D t1, Vector3D t2) {
this.x = (int)(t1.getX() + t2.getX());
this.y = (int)(t1.getY() + t2.getY());
this.z = (int)(t1.getZ() + t2.getZ());
}
@Override
public void add(Vector3D t1) {
this.x = (int)(this.x + t1.getX());
this.y = (int)(this.y + t1.getY());
this.z = (int)(this.z + t1.getZ());
}
@Override
public void scaleAdd(int s, Vector3D t1, Vector3D t2) {
this.x = (int)(s * t1.getX() + t2.getX());
this.y = (int)(s * t1.getY() + t2.getY());
this.z = (int)(s * t1.getZ() + t2.getZ());
}
@Override
public void scaleAdd(double s, Vector3D t1, Vector3D t2) {
this.x = (int)(s * t1.getX() + t2.getX());
this.y = (int)(s * t1.getY() + t2.getY());
this.z = (int)(s * t1.getZ() + t2.getZ());
}
@Override
public void scaleAdd(int s, Vector3D t1) {
this.x = (int)(s * this.x + t1.getX());
this.y = (int)(s * this.y + t1.getY());
this.z = (int)(s * this.z + t1.getZ());
}
@Override
public void scaleAdd(double s, Vector3D t1) {
this.x = (int)(s * this.x + t1.getX());
this.y = (int)(s * this.y + t1.getY());
this.z = (int)(s * this.z + t1.getZ());
}
@Override
public void sub(Vector3D t1, Vector3D t2) {
this.x = (int)(t1.getX() - t2.getX());
this.y = (int)(t1.getY() - t2.getY());
this.z = (int)(t1.getZ() - t2.getZ());
}
@Override
public void sub(Point3D t1, Point3D t2) {
this.x = (int)(t1.getX() - t2.getX());
this.y = (int)(t1.getY() - t2.getY());
this.z = (int)(t1.getZ() - t2.getZ());
}
@Override
public void sub(Vector3D t1) {
this.x = (int)(this.x - t1.getX());
this.y = (int)(this.y - t1.getY());
this.z = (int)(this.z - t1.getZ());
}
@Pure
@Override
public Vector3D cross(Vector3D v1) {
return crossLeftHand(v1);
}
@Override
public void cross(Vector3D v1, Vector3D v2) {
crossLeftHand(v1, v2);
}
@Pure
@Override@SuppressWarnings("hiding")
public Vector3D crossLeftHand(Vector3D v1) {
double x = v1.getY()*getZ() - v1.getZ()*getY();
double y = v1.getZ()*getX() - v1.getX()*getZ();
double z = v1.getX()*getY() - v1.getY()*getX();
return new Vector3i(x,y,z);
}
@Override@SuppressWarnings("hiding")
public void crossLeftHand(Vector3D v1, Vector3D v2) {
double x = v2.getY()*v1.getZ() - v2.getZ()*v1.getY();
double y = v2.getZ()*v1.getX() - v2.getX()*v1.getZ();
double z = v2.getX()*v1.getY() - v2.getY()*v1.getX();
set(x,y,z);
}
@Pure
@Override@SuppressWarnings("hiding")
public Vector3D crossRightHand(Vector3D v1) {
double x = getY()*v1.getZ() - getZ()*v1.getY();
double y = getZ()*v1.getX() - getX()*v1.getZ();
double z = getX()*v1.getY() - getY()*v1.getX();
return new Vector3i(x,y,z);
}
@Override@SuppressWarnings("hiding")
public void crossRightHand(Vector3D v1, Vector3D v2) {
double x = v1.getY()*v2.getZ() - v1.getZ()*v2.getY();
double y = v1.getZ()*v2.getX() - v1.getX()*v2.getZ();
double z = v1.getX()*v2.getY() - v1.getY()*v2.getX();
set(x,y,z);
}
@Override
public void turnVector(Vector3D axis, double angle) {
Transform3D mat = new Transform3D();
mat.setRotation(new Quaternion(axis, angle));
mat.transform(this);
}
@Pure
@Override
public boolean isUnitVector() {
return MathUtil.isEpsilonEqual(lengthSquared(), 1.);
}
@Pure
@Override
public boolean isColinear(Vector3D v) {
int cx = iy() * v.iz() - iz() * v.iy();
int cy = iz() * v.ix() - ix() * v.iz();
int cz = ix() * v.iy() - iy() * v.ix();
int sum = cx * cx + cy * cy + cz * cz;
return sum == 0;
}
@Override
public void setLength(double newLength) {
double nl = Math.max(0, newLength);
double l = length();
if (l != 0) {
double f = nl / l;
this.x *= f;
this.y *= f;
this.z *= f;
} else {
this.x = (int) newLength;
this.y = 0;
this.z = 0;
}
}
@Pure
@Override
public Vector3D toUnmodifiable() {
return new UnmodifiableVector3i();
}
/**
* @author $Author: sgalland$
* @version $Name$ $Revision$ $Date$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
private class UnmodifiableVector3i implements Vector3D {
private static final long serialVersionUID = 6113750458070037483L;
public UnmodifiableVector3i() {
//
}
@Pure
@Override
public Vector3D clone() {
try {
return (Vector3D) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e);
}
}
@Override
public void absolute() {
throw new UnsupportedOperationException();
}
@Override
public void absolute(Vector3D t) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("hiding")
@Override
public void add(int x, int y, int z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void add(double x, double y, double z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void addX(int x) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void addX(double x) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void addY(int y) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void addY(double y) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void addZ(int z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void addZ(double z) {
throw new UnsupportedOperationException();
}
@Override
public void clamp(int min, int max) {
throw new UnsupportedOperationException();
}
@Override
public void clamp(double min, double max) {
throw new UnsupportedOperationException();
}
@Override
public void clampMin(int min) {
throw new UnsupportedOperationException();
}
@Override
public void clampMin(double min) {
throw new UnsupportedOperationException();
}
@Override
public void clampMax(int max) {
throw new UnsupportedOperationException();
}
@Override
public void clampMax(double max) {
throw new UnsupportedOperationException();
}
@Override
public void clamp(int min, int max, Vector3D t) {
throw new UnsupportedOperationException();
}
@Override
public void clamp(double min, double max, Vector3D t) {
throw new UnsupportedOperationException();
}
@Override
public void clampMin(int min, Vector3D t) {
throw new UnsupportedOperationException();
}
@Override
public void clampMin(double min, Vector3D t) {
throw new UnsupportedOperationException();
}
@Override
public void clampMax(int max, Vector3D t) {
throw new UnsupportedOperationException();
}
@Override
public void clampMax(double max, Vector3D t) {
throw new UnsupportedOperationException();
}
@Override
public void get(Vector3D t) {
Vector3i.this.get(t);
}
@Override
public void get(int[] t) {
Vector3i.this.get(t);
}
@Override
public void get(double[] t) {
Vector3i.this.get(t);
}
@Override
public void negate(Vector3D t1) {
throw new UnsupportedOperationException();
}
@Override
public void negate() {
throw new UnsupportedOperationException();
}
@Override
public void scale(int s, Vector3D t1) {
throw new UnsupportedOperationException();
}
@Override
public void scale(double s, Vector3D t1) {
throw new UnsupportedOperationException();
}
@Override
public void scale(int s) {
throw new UnsupportedOperationException();
}
@Override
public void scale(double s) {
throw new UnsupportedOperationException();
}
@Override
public void set(Tuple3D<?> t1) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void set(int x, int y, int z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void set(double x, double y, double z) {
throw new UnsupportedOperationException();
}
@Override
public void set(int[] t) {
throw new UnsupportedOperationException();
}
@Override
public void set(double[] t) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public double getX() {
return Vector3i.this.getX();
}
@Pure
@Override
public int ix() {
return Vector3i.this.ix();
}
@Override@SuppressWarnings("hiding")
public void setX(int x) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void setX(double x) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public double getY() {
return Vector3i.this.getY();
}
@Pure
@Override
public int iy() {
return Vector3i.this.iy();
}
@Override@SuppressWarnings("hiding")
public void setY(int y) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void setY(double y) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public double getZ() {
return Vector3i.this.getZ();
}
@Pure
@Override
public int iz() {
return Vector3i.this.iz();
}
@Override@SuppressWarnings("hiding")
public void setZ(int z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void setZ(double z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void sub(int x, int y, int z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void sub(double x, double y, double z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void subX(int x) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void subX(double x) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void subY(int y) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void subY(double y) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void subZ(int z) {
throw new UnsupportedOperationException();
}
@Override@SuppressWarnings("hiding")
public void subZ(double z) {
throw new UnsupportedOperationException();
}
@Override
public void interpolate(Vector3D t1, Vector3D t2, double alpha) {
throw new UnsupportedOperationException();
}
@Override
public void interpolate(Vector3D t1, double alpha) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public boolean equals(Tuple3D<?> t1) {
return Vector3i.this.equals(t1);
}
@Pure
@Override
public int hashCode() {
return Vector3i.this.hashCode();
}
@Pure
@Override
public boolean epsilonEquals(Vector3D t1, double epsilon) {
return Vector3i.this.epsilonEquals(t1, epsilon);
}
@Override
public void add(Vector3D t1, Vector3D t2) {
throw new UnsupportedOperationException();
}
@Override
public void add(Vector3D t1) {
throw new UnsupportedOperationException();
}
@Override
public void scaleAdd(int s, Vector3D t1, Vector3D t2) {
throw new UnsupportedOperationException();
}
@Override
public void scaleAdd(double s, Vector3D t1, Vector3D t2) {
throw new UnsupportedOperationException();
}
@Override
public void scaleAdd(int s, Vector3D t1) {
throw new UnsupportedOperationException();
}
@Override
public void scaleAdd(double s, Vector3D t1) {
throw new UnsupportedOperationException();
}
@Override
public void sub(Vector3D t1, Vector3D t2) {
throw new UnsupportedOperationException();
}
@Override
public void sub(Point3D t1, Point3D t2) {
throw new UnsupportedOperationException();
}
@Override
public void sub(Vector3D t1) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public double dot(Vector3D v1) {
return Vector3i.this.dot(v1);
}
@Pure
@Override
public Vector3D cross(Vector3D v1) {
return Vector3i.this.cross(v1);
}
@Override
public void cross(Vector3D v1, Vector3D v2) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public Vector3D crossLeftHand(Vector3D v1) {
return Vector3i.this.crossLeftHand(v1);
}
@Override
public void crossLeftHand(Vector3D v1, Vector3D v2) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public Vector3D crossRightHand(Vector3D v1) {
return Vector3i.this.crossRightHand(v1);
}
@Override
public void crossRightHand(Vector3D v1, Vector3D v2) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public double length() {
return Vector3i.this.length();
}
@Pure
@Override
public double lengthSquared() {
return Vector3i.this.lengthSquared();
}
@Override
public void normalize(Vector3D v1) {
throw new UnsupportedOperationException();
}
@Override
public void normalize() {
throw new UnsupportedOperationException();
}
@Pure
@Override
public double angle(Vector3D v1) {
return Vector3i.this.angle(v1);
}
@Override
public void turnVector(Vector3D axis, double angle) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public boolean isUnitVector() {
return Vector3i.this.isUnitVector();
}
@Override
public void setLength(double newLength) {
throw new UnsupportedOperationException();
}
@Pure
@Override
public Vector3D toUnmodifiable() {
return this;
}
@Pure
@Override
public double perp(Vector3D v) {
return Vector3i.this.perp(v);
}
@Pure
@Override
public boolean isColinear(Vector3D v) {
return Vector3i.this.isColinear(v);
}
}
}