/*
* Copyright (c) 2010, Frederik Vanhoutte 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
* 2.1 of the License, or (at your option) any later version.
* http://creativecommons.org/licenses/LGPL/2.1/ 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., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301 USA
*/
package wblut.geom;
import wblut.WB_Epsilon;
import wblut.math.WB_Fast;
import wblut.math.WB_M33;
import wblut.math.WB_MTRandom;
// TODO: Auto-generated Javadoc
/**
* The Class WB_Point3d.
*
* @author Frederik Vanhoutte (W:Blut) 2010
*/
public class WB_Point3d implements Comparable<WB_Point3d> {
/**
* Zero.
*
* @return the w b_ point3d
*/
public static WB_Point3d ZERO() {
return new WB_Point3d(0, 0, 0);
}
/**
* X.
*
* @return the w b_ point3d
*/
public static WB_Point3d X() {
return new WB_Point3d(1, 0, 0);
}
/**
* Y.
*
* @return the w b_ point3d
*/
public static WB_Point3d Y() {
return new WB_Point3d(0, 1, 0);
}
/**
* Z.
*
* @return the w b_ point3d
*/
public static WB_Point3d Z() {
return new WB_Point3d(0, 0, 1);
}
/** Coordinates. */
public double x, y, z;
/**
* Instantiates a new WB_XYZ.
*/
public WB_Point3d() {
x = y = z = 0;
}
/**
* Instantiates a new WB_XYZ.
*
* @param x the x
* @param y the y
* @param z the z
*/
public WB_Point3d(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Instantiates a new WB_XYZ.
*
* @param x the x
* @param y the y
*/
public WB_Point3d(final double x, final double y) {
this.x = x;
this.y = y;
z = 0;
}
/**
* Instantiates a new WB_XYZ.
*
* @param v the v
*/
public WB_Point3d(final WB_Point3d v) {
x = v.x;
y = v.y;
z = v.z;
}
/**
* return copy.
*
* @return copy
*/
public WB_Point3d get() {
return new WB_Point3d(x, y, z);
}
/**
* Set coordinates.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void set(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* Set coordinates.
*
* @param x the x
* @param y the y
*/
public void set(final double x, final double y) {
this.x = x;
this.y = y;
z = 0;
}
/**
* Set coordinates.
*
* @param v the v
*/
public void set(final WB_Point3d v) {
x = v.x;
y = v.y;
z = v.z;
}
/**
* Invert.
*/
public void invert() {
x *= -1;
y *= -1;
z *= -1;
}
/**
* Normalize.
*
* @return the double
*/
public double normalize() {
final double d = mag();
if (WB_Epsilon.isZero(d)) {
set(0, 0, 0);
} else {
set(x / d, y / d, z / d);
}
return d;
}
/**
* Trim.
*
* @param d the d
*/
public void trim(final double d) {
if (mag2() > d * d) {
normalize();
mult(d);
}
}
/**
* Scale.
*
* @param f scale factor
* @return self
*/
public WB_Point3d scale(final double f) {
x *= f;
y *= f;
z *= f;
return this;
}
/**
* Scale.
*
* @param fx scale factor
* @param fy scale factor
* @param fz scale factor
* @return self
*/
public WB_Point3d scale(final double fx, final double fy, final double fz) {
x *= fx;
y *= fy;
z *= fz;
return this;
}
/**
* Scale .
*
* @param f scale factor
* @param result WB_XYZ to store result
*/
public void scaleInto(final double f, final WB_Point3d result) {
result.x = x * f;
result.y = y * f;
result.z = z * f;
}
/**
* Adds the.
*
* @param x the x
* @param y the y
* @param z the z
* @return self
*/
public WB_Point3d add(final double x, final double y, final double z) {
this.x += x;
this.y += y;
this.z += z;
return this;
}
/**
* Adds the.
*
* @param p the p
* @return self
*/
public WB_Point3d add(final WB_Point3d p) {
x += p.x;
y += p.y;
z += p.z;
return this;
}
/**
* Adds the into.
*
* @param x the x
* @param y the y
* @param z the z
* @param result the result
*/
public void addInto(final double x, final double y, final double z,
final WB_Point3d result) {
result.x = (this.x + x);
result.y = (this.y + y);
result.z = (this.z + z);
}
/**
* Adds the into.
*
* @param p the p
* @param result the result
*/
public void addInto(final WB_Point3d p, final WB_Point3d result) {
result.x = x + p.x;
result.y = y + p.y;
result.z = z + p.z;
}
/**
* Adds the and copy.
*
* @param x the x
* @param y the y
* @param z the z
* @return new WB_XYZW
*/
public WB_Point3d addAndCopy(final double x, final double y, final double z) {
return new WB_Point3d(this.x + x, this.y + y, this.z + z);
}
/**
* Adds the and copy.
*
* @param p the p
* @return new WB_XYZ
*/
public WB_Point3d addAndCopy(final WB_Point3d p) {
return new WB_Point3d(x + p.x, y + p.y, z + p.z);
}
/**
* Adds the.
*
* @param p the p
* @param f the f
* @return self
*/
public WB_Point3d add(final WB_Point3d p, final double f) {
x += f * p.x;
y += f * p.y;
z += f * p.z;
return this;
}
/**
* Adds the.
*
* @param x the x
* @param y the y
* @param z the z
* @param f the f
* @return self
*/
public WB_Point3d add(final double x, final double y, final double z,
final double f) {
this.x += f * x;
this.y += f * y;
this.z += f * z;
return this;
}
/**
* Adds the into.
*
* @param x the x
* @param y the y
* @param z the z
* @param f the f
* @param result the result
*/
public void addInto(final double x, final double y, final double z,
final double f, final WB_Point3d result) {
result.x = (this.x + f * x);
result.y = (this.y + f * y);
result.z = (this.z + f * z);
}
/**
* Adds the into.
*
* @param p the p
* @param f the f
* @param result the result
*/
public void addInto(final WB_Point3d p, final double f,
final WB_Point3d result) {
result.x = x + f * p.x;
result.y = y + f * p.y;
result.z = z + f * p.z;
}
/**
* Adds the and copy.
*
* @param x the x
* @param y the y
* @param z the z
* @param f the f
* @return new WB_XYZW
*/
public WB_Point3d addAndCopy(final double x, final double y,
final double z, final double f) {
return new WB_Point3d(this.x + f * x, this.y + f * y, this.z + f * z);
}
/**
* Adds the and copy.
*
* @param p the p
* @param f the f
* @return new WB_XYZ
*/
public WB_Point3d addAndCopy(final WB_Point3d p, final double f) {
return new WB_Point3d(x + f * p.x, y + f * p.y, z + f * p.z);
}
/**
* Sub.
*
* @param x the x
* @param y the y
* @param z the z
* @return self
*/
public WB_Point3d sub(final double x, final double y, final double z) {
this.x -= x;
this.y -= y;
this.z -= z;
return this;
}
/**
* Sub.
*
* @param v the v
* @return self
*/
public WB_Point3d sub(final WB_Point3d v) {
x -= v.x;
y -= v.y;
z -= v.z;
return this;
}
/**
* Sub into.
*
* @param x the x
* @param y the y
* @param z the z
* @param result the result
*/
public void subInto(final double x, final double y, final double z,
final WB_Point3d result) {
result.x = (this.x - x);
result.y = (this.y - y);
result.z = (this.z - z);
}
/**
* Sub into.
*
* @param p the p
* @param result the result
*/
public void subInto(final WB_Point3d p, final WB_Point3d result) {
result.x = x - p.x;
result.y = y - p.y;
result.z = z - p.z;
}
/**
* Sub and copy.
*
* @param x the x
* @param y the y
* @param z the z
* @return new WB_XYZ
*/
public WB_Point3d subAndCopy(final double x, final double y, final double z) {
return new WB_Point3d(this.x - x, this.y - y, this.z - z);
}
/**
* Sub and copy.
*
* @param p the p
* @return new WB_XYZ
*/
public WB_Point3d subAndCopy(final WB_Point3d p) {
return new WB_Point3d(x - p.x, y - p.y, z - p.z);
}
/**
* Subtract to vector.
*
* @param x the x
* @param y the y
* @param z the z
* @return new WB_Vector
*/
public WB_Vector3d subToVector(final double x, final double y,
final double z) {
return new WB_Vector3d(this.x - x, this.y - y, this.z - z);
}
/**
* Subtract to vector.
*
* @param p point
* @return new WB_Vector
*/
public WB_Vector3d subToVector(final WB_Point3d p) {
return new WB_Vector3d(x - p.x, y - p.y, z - p.z);
}
/**
* Mult.
*
* @param f the f
* @return self
*/
public WB_Point3d mult(final double f) {
scale(f);
return this;
}
/**
* Mult into.
*
* @param f the f
* @param result the result
*/
public void multInto(final double f, final WB_Point3d result) {
scaleInto(f, result);
}
/**
* Mult and copy.
*
* @param f the f
* @return new WB_XYZW
*/
public WB_Point3d multAndCopy(final double f) {
return new WB_Point3d(x * f, y * f, z * f);
}
/**
* Div.
*
* @param f the f
* @return self
*/
public WB_Point3d div(final double f) {
return mult(1.0 / f);
}
/**
* Div into.
*
* @param f the f
* @param result the result
*/
public void divInto(final double f, final WB_Point3d result) {
multInto(1.0 / f, result);
}
/**
* Div and copy.
*
* @param f the f
* @return new WB_XYZW
*/
public WB_Point3d divAndCopy(final double f) {
return multAndCopy(1.0 / f);
}
/**
* Dot product.
*
* @param p the p
* @param q the q
* @return dot product
*/
public static double dot(final WB_Point3d p, final WB_Point3d q) {
return (p.x * q.x + p.y * q.y + p.z * q.z);
}
/**
* Dot product.
*
* @param p the p
* @return dot product
*/
public double dot(final WB_Point3d p) {
return (p.x * x + p.y * y + p.z * z);
}
/**
* Angle to vector. Normalized vectors are assumed.
*
* @param p normalized point, vector or normal
* @return angle
*/
public double angleNorm(final WB_Point3d p) {
return Math.acos(p.x * x + p.y * y + p.z * z);
}
/**
* Absolute value of dot product.
*
* @param p the p
* @param q the q
* @return absolute value of dot product
*/
public static double absDot(final WB_Point3d p, final WB_Point3d q) {
return WB_Fast.abs(p.x * q.x + p.y * q.y + p.z * q.z);
}
/**
* Absolute value of dot product.
*
* @param p the p
* @return absolute value of dot product
*/
public double absDot(final WB_Point3d p) {
return WB_Fast.abs(p.x * x + p.y * y + p.z * z);
}
/**
* Cross product. Internal use only.
*
* @param p the p
* @return the w b_ point3d
*/
public WB_Point3d cross(final WB_Point3d p) {
return new WB_Point3d(y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y
* p.x);
}
/**
* Cross product. Internal use only.
*
* @param p the p
* @param q the q
* @return the w b_ point3d
*/
public static WB_Point3d cross(final WB_Point3d p, final WB_Point3d q) {
return new WB_Point3d(p.y * q.z - p.z * q.y, p.z * q.x - p.x * q.z, p.x
* q.y - p.y * q.x);
}
/**
* Cross product. Internal use only.
*
* @param p the p
* @param result the result
*/
public void crossInto(final WB_Point3d p, final WB_Point3d result) {
result.x = y * p.z - z * p.y;
result.y = z * p.x - x * p.z;
result.z = x * p.y - y * p.x;
}
/**
* Scalar triple product.
*
* @param p the p
* @param q the q
* @param r the r
* @return scalar triple product
*/
public static double scalarTriple(final WB_Point3d p, final WB_Point3d q,
final WB_Point3d r) {
return (dot(p, cross(q, r)));
}
/**
* Scalar triple product.
*
* @param p the p
* @param q the q
* @return scalar triple product.
*/
public double scalarTriple(final WB_Point3d p, final WB_Point3d q) {
return (dot(this, cross(p, q)));
}
/**
* Tensor.
*
* @param p the p
* @param q the q
* @return the w b_ m33
*/
public static WB_M33 tensor(final WB_Point3d p, final WB_Point3d q) {
return new WB_M33(p.x * q.x, p.x * q.y, p.x * q.z, p.y * q.x,
p.y * q.y, p.y * q.z, p.z * q.x, p.z * q.y, p.z * q.z);
}
/**
* Tensor.
*
* @param q the q
* @return the w b_ m33
*/
public WB_M33 tensor(final WB_Point3d q) {
return new WB_M33(x * q.x, x * q.y, x * q.z, y * q.x, y * q.y, y * q.z,
z * q.x, z * q.y, z * q.z);
}
/**
* Get squared magnitude.
*
* @return squared magnitude
*/
public double mag2() {
return x * x + y * y + z * z;
}
/**
* Get magnitude.
*
* @return magnitude
*/
public double mag() {
return Math.sqrt(x * x + y * y + z * z);
}
/**
* Checks if vector is zero-vector.
*
* @return true, if zero
*/
public boolean isZero() {
return (mag2() < WB_Epsilon.SQEPSILON);
}
/*
* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(final WB_Point3d otherXYZ) {
int _tmp = WB_Epsilon.compareAbs(x, otherXYZ.x);
if (_tmp != 0) {
return _tmp;
}
_tmp = WB_Epsilon.compareAbs(y, otherXYZ.y);
if (_tmp != 0) {
return _tmp;
}
_tmp = WB_Epsilon.compareAbs(z, otherXYZ.z);
return _tmp;
}
/**
* Compare to y1st.
*
* @param otherXYZ the other xyz
* @return the int
*/
public int compareToY1st(final WB_Point3d otherXYZ) {
int _tmp = WB_Epsilon.compareAbs(y, otherXYZ.y);
if (_tmp != 0) {
return _tmp;
}
_tmp = WB_Epsilon.compareAbs(x, otherXYZ.x);
if (_tmp != 0) {
return _tmp;
}
_tmp = WB_Epsilon.compareAbs(z, otherXYZ.z);
return _tmp;
}
/**
* Smaller than.
*
* @param otherXYZ point, vector or normal
* @return true, if successful
*/
public boolean smallerThan(final WB_Point3d otherXYZ) {
int _tmp = WB_Epsilon.compareAbs(x, otherXYZ.x);
if (_tmp != 0) {
return (_tmp < 0);
}
_tmp = WB_Epsilon.compareAbs(y, otherXYZ.y);
if (_tmp != 0) {
return (_tmp < 0);
}
_tmp = WB_Epsilon.compareAbs(z, otherXYZ.z);
return (_tmp < 0);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "XYZ [x=" + x + ", y=" + y + ", z=" + z + "]";
}
/**
* Get coordinate from index value.
*
* @param i 0,1,2
* @return x-,y- or z-coordinate
*/
public double get(final int i) {
if (i == 0) {
return x;
}
if (i == 1) {
return y;
}
if (i == 2) {
return z;
}
return Double.NaN;
}
/**
* Set coordinate with index value.
*
* @param i 0,1,2
* @param v x-,y- or z-coordinate
*/
public void set(final int i, final double v) {
if (i == 0) {
x = v;
} else if (i == 1) {
y = v;
} else if (i == 2) {
z = v;
}
}
/**
* Get x-coordinate as float.
*
* @return x
*/
public float xf() {
return (float) x;
}
/**
* Get y-coordinate as float.
*
* @return y
*/
public float yf() {
return (float) y;
}
/**
* Get z-coordinate as float.
*
* @return z
*/
public float zf() {
return (float) z;
}
/**
* Is vector parallel to other vector.
*
* @param p the p
* @return true, if parallel
*/
public boolean isParallel(final WB_Point3d p) {
return (cross(p).mag2() / (p.mag2() * mag2()) < WB_Epsilon.SQEPSILON);
}
/**
* Is vector parallel to other vector.
*
* @param p the p
* @param t threshold value = (sin(threshold angle))^2
* @return true, if parallel
*/
public boolean isParallel(final WB_Point3d p, final double t) {
return (cross(p).mag2() / (p.mag2() * mag2()) < t
+ WB_Epsilon.SQEPSILON);
}
/**
* Is normalized vector parallel to other normalized vector.
*
* @param p the p
* @return true, if parallel
*/
public boolean isParallelNorm(final WB_Point3d p) {
return (cross(p).mag2() < WB_Epsilon.SQEPSILON);
}
/**
* Is normalized vector parallel to other normalized vector.
*
* @param p the p
* @param t threshold value = (sin(threshold angle))^2
* @return true, if parallel
*/
public boolean isParallelNorm(final WB_Point3d p, final double t) {
return (cross(p).mag2() < t + WB_Epsilon.SQEPSILON);
}
/**
* Calculate hash code.
*
* @param x the x
* @param y the y
* @param z the z
* @return the int
*/
protected static int calculateHashCode(final double x, final double y,
final double z) {
int result = 17;
final long a = Double.doubleToLongBits(x);
result += 31 * result + (int) (a ^ (a >>> 32));
final long b = Double.doubleToLongBits(y);
result += 31 * result + (int) (b ^ (b >>> 32));
final long c = Double.doubleToLongBits(z);
result += 31 * result + (int) (c ^ (c >>> 32));
return result;
}
/**
* Calculate hash code.
*
* @return the int
*/
protected int calculateHashCode() {
int result = 17;
final long a = Double.doubleToLongBits(x);
result += 31 * result + (int) (a ^ (a >>> 32));
final long b = Double.doubleToLongBits(y);
result += 31 * result + (int) (b ^ (b >>> 32));
final long c = Double.doubleToLongBits(z);
result += 31 * result + (int) (c ^ (c >>> 32));
return result;
}
/**
* Move to position.
*
* @param x the x
* @param y the y
* @param z the z
* @return self
*/
public WB_Point3d moveTo(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
/**
* Move to position.
*
* @param x the x
* @param y the y
* @return self
*/
public WB_Point3d moveTo(final double x, final double y) {
this.x = x;
this.y = y;
z = 0;
return this;
}
/**
* Move to position.
*
* @param p point, vector or normal
* @return self
*/
public WB_Point3d moveTo(final WB_Point3d p) {
x = p.x;
y = p.y;
z = p.z;
return this;
}
/**
* Move by vector.
*
* @param x the x
* @param y the y
* @param z the z
* @return self
*/
public WB_Point3d moveBy(final double x, final double y, final double z) {
this.x += x;
this.y += y;
this.z += z;
return this;
}
/**
* Move by vector.
*
* @param v point, vector or normal
* @return self
*/
public WB_Point3d moveBy(final WB_Point3d v) {
x += v.x;
y += v.y;
z += v.z;
return this;
}
/**
* Move by vector.
*
* @param x the x
* @param y the y
* @param z the z
* @param result WB_XYZ to store result
*/
public void moveByInto(final double x, final double y, final double z,
final WB_Point3d result) {
result.x = this.x + x;
result.y = this.y + y;
result.z = this.z + z;
}
/**
* Move by vector.
*
* @param v point, vector or normal
* @param result WB_XYZ to store result
*/
public void moveByInto(final WB_Point3d v, final WB_Point3d result) {
result.x = x + v.x;
result.y = y + v.y;
result.z = z + v.z;
}
/**
* Move by vector.
*
* @param x the x
* @param y the y
* @param z the z
* @return new WB_XYZ
*/
public WB_Point3d moveByAndCopy(final double x, final double y,
final double z) {
return new WB_Point3d(this.x + x, this.y + y, this.z + z);
}
/**
* Move by vector.
*
* @param v point, vector or normal
* @return new WB_XYZ
*/
public WB_Point3d moveByAndCopy(final WB_Point3d v) {
return new WB_Point3d(x + v.x, y + v.y, z + v.z);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
/**
* Rotate vertex around an arbitrary axis.
*
* @param angle angle
* @param p1x x-coordinate of first point on axis
* @param p1y y-coordinate of first point on axis
* @param p1z z-coordinate of first point on axis
* @param p2x x-coordinate of second point on axis
* @param p2y y-coordinate of second point on axis
* @param p2z z-coordinate of second point on axis
*/
public void rotateAboutAxis(final double angle, final double p1x,
final double p1y, final double p1z, final double p2x,
final double p2y, final double p2z) {
final WB_Transform raa = new WB_Transform();
raa.addRotateAboutAxis(angle, new WB_Point3d(p1x, p1y, p1z),
new WB_Vector3d(p2x - p1x, p2y - p1y, p2z - p1z));
raa.applySelf(this);
}
/**
* Rotate vertex around an arbitrary axis.
*
* @param angle angle
* @param p1 first point on axis
* @param p2 second point on axis
*/
public void rotateAboutAxis(final double angle, final WB_Point3d p1,
final WB_Point3d p2) {
final WB_Transform raa = new WB_Transform();
raa.addRotateAboutAxis(angle, p1, p2.subToVector(p1));
raa.applySelf(this);
}
/**
* Rotate vertex around an arbitrary axis.
*
* @param angle angle
* @param p rotation point
* @param a axis
*/
public void rotateAboutAxis(final double angle, final WB_Point3d p,
final WB_Vector3d a) {
final WB_Transform raa = new WB_Transform();
raa.addRotateAboutAxis(angle, p, a);
raa.applySelf(this);
}
// Get n points in range (-x,x), (-y,y),(-z,z)
/**
* Random points.
*
* @param n the n
* @param x the x
* @param y the y
* @param z the z
* @return the w b_ point3d[]
*/
public static WB_Point3d[] randomPoints(final int n, final double x,
final double y, final double z) {
final WB_MTRandom mtr = new WB_MTRandom();
final WB_Point3d[] points = new WB_Point3d[n];
for (int i = 0; i < n; i++) {
points[i] = new WB_Point3d(-x + 2 * mtr.nextDouble() * x, -y + 2
* mtr.nextDouble() * y, -z + 2 * mtr.nextDouble() * z);
}
return points;
}
// Get n points in range (lx,ux), (ly,uy),(lz,uz)
/**
* Random points.
*
* @param n the n
* @param lx the lx
* @param ly the ly
* @param lz the lz
* @param ux the ux
* @param uy the uy
* @param uz the uz
* @return the w b_ point3d[]
*/
public static WB_Point3d[] randomPoints(final int n, final double lx,
final double ly, final double lz, final double ux, final double uy,
final double uz) {
final WB_MTRandom mtr = new WB_MTRandom();
final WB_Point3d[] points = new WB_Point3d[n];
final double dx = ux - lx;
final double dy = uy - ly;
final double dz = uz - lz;
for (int i = 0; i < n; i++) {
points[i] = new WB_Point3d(lx + mtr.nextDouble() * dx, ly
+ mtr.nextDouble() * dy, lz + mtr.nextDouble() * dz);
}
return points;
}
/**
* To vector.
*
* @return the w b_ vector3d
*/
public WB_Vector3d toVector() {
return new WB_Vector3d(x, y, z);
}
/**
* To normal.
*
* @return the w b_ normal3d
*/
public WB_Normal3d toNormal() {
return new WB_Normal3d(x, y, z);
}
/**
* Interpolate.
*
* @param p0 the p0
* @param p1 the p1
* @param t the t
* @return the w b_ point
*/
public static WB_Point3d interpolate(final WB_Point3d p0,
final WB_Point3d p1, final double t) {
return new WB_Point3d(p0.x + t * (p1.x - p0.x), p0.y + t
* (p1.y - p0.y), p0.z + t * (p1.z - p0.z));
}
/**
* Angle between.
*
* @param corner the corner
* @param p1 the p1
* @param p2 the p2
* @return the double
*/
public static double angleBetween(final WB_Point3d corner,
final WB_Point3d p1, final WB_Point3d p2) {
final WB_Point3d v0 = p1.subAndCopy(corner);
final WB_Point3d v1 = p2.subAndCopy(corner);
v0.normalize();
v1.normalize();
return Math.acos(v0.dot(v1));
}
/**
* Cos angle between.
*
* @param corner the corner
* @param p1 the p1
* @param p2 the p2
* @return the double
*/
public static double cosAngleBetween(final WB_Point3d corner,
final WB_Point3d p1, final WB_Point3d p2) {
final WB_Point3d v0 = p1.subAndCopy(corner);
final WB_Point3d v1 = p2.subAndCopy(corner);
v0.normalize();
v1.normalize();
return v0.dot(v1);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
// Algorithm from Effective Java by Joshua Bloch
int result = 17;
result = 37 * result + hashCode(x);
result = 37 * result + hashCode(y);
result = 37 * result + hashCode(z);
return result;
}
/**
* Hash code.
*
* @param x the x
* @return the int
*/
public static int hashCode(final double x) {
long f = Double.doubleToLongBits(x);
return (int) (f ^ (f >>> 32));
}
/**
* Coords.
*
* @return the double[]
*/
public double[] coords(){
return new double[] {x,y,z};
}
}