/******************************************************************************* * This file is part of Goko. * * Goko is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Goko 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Goko. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package org.goko.core.math; import java.math.BigDecimal; import javax.vecmath.Point3d; import javax.vecmath.Point3f; import javax.vecmath.Vector3d; import org.goko.core.common.measure.SIPrefix; import org.goko.core.common.measure.Units; import org.goko.core.common.measure.quantity.Angle; import org.goko.core.common.measure.quantity.AngleUnit; import org.goko.core.common.measure.quantity.Length; import org.goko.core.common.measure.quantity.Quantity; import org.goko.core.common.measure.quantity.QuantityUtils; import org.goko.core.common.measure.units.Unit; import org.goko.core.common.utils.BigDecimalUtils; public class Tuple6b { private Length x; private Length y; private Length z; private Angle a; private Angle b; private Angle c; public Tuple6b(){ this(SIPrefix.MILLI(Units.METRE), AngleUnit.DEGREE_ANGLE); } /** * @param x * @param y * @param z * @param a * @param b * @param c */ public Tuple6b(Length x, Length y, Length z, Angle a, Angle b, Angle c) { super(); this.x = x; this.y = y; this.z = z; this.a = a; this.b = b; this.c = c; } public Tuple6b(Length x, Length y, Length z) { this(x,y,z, Angle.ZERO, Angle.ZERO, Angle.ZERO); } public Tuple6b(Tuple6b tuple){ this.x = tuple.x; this.y = tuple.y; this.z = tuple.z; this.a = tuple.a; this.b = tuple.b; this.c = tuple.c; } public Tuple6b(Unit<Length> unit, Unit<Angle> angleUnit) { super(); this.x = Length.ZERO; this.y = Length.ZERO; this.z = Length.ZERO; this.a = Angle.ZERO; this.b = Angle.ZERO; this.c = Angle.ZERO; } /** * @param x * @param y * @param z */ public Tuple6b(double x, double y, double z, Unit<Length> unit) { super(); this.x = Length.valueOf(new BigDecimal(String.valueOf(x)), unit); this.y = Length.valueOf(new BigDecimal(String.valueOf(y)), unit); this.z = Length.valueOf(new BigDecimal(String.valueOf(z)), unit); } /** * @param x * @param y * @param z */ public Tuple6b(BigDecimal x, BigDecimal y, BigDecimal z, Unit<Length> unit) { super(); this.x = Length.valueOf(x, unit); this.y = Length.valueOf(y, unit); this.z = Length.valueOf(z, unit); } /** * @param x * @param y * @param z * @param a * @param b * @param c */ public Tuple6b(BigDecimal x, BigDecimal y, BigDecimal z, BigDecimal a, BigDecimal b, BigDecimal c, Unit<Length> unit, Unit<Angle> angleUnit) { super(); this.x = Length.valueOf(x, unit); this.y = Length.valueOf(y, unit); this.z = Length.valueOf(z, unit); this.a = Angle.valueOf(a, angleUnit); this.b = Angle.valueOf(b, angleUnit); this.c = Angle.valueOf(c, angleUnit); } public Tuple6b(Unit<Length> unit, Length qx, Length qy, Length qz) { super(); this.x = qx.to(unit); this.y = qy.to(unit); this.z = qz.to(unit); } public void updateRelative(Tuple6b position){ this.x = atomUpdateRelative(x, position.x); this.y = atomUpdateRelative(y, position.y); this.z = atomUpdateRelative(z, position.z); this.a = atomUpdateRelative(a, position.a); this.b = atomUpdateRelative(b, position.b); this.c = atomUpdateRelative(c, position.c); } protected <Q extends Quantity<Q>> Q atomUpdateRelative(Q a, Q b) { if( a != null && b!=null){ return a.add(b); }else if( a != null){ return a; }else if(b != null){ return b; } return null; } public Tuple6b min(Tuple6b t){ Tuple6b result = new Tuple6b(this); result.x = QuantityUtils.min(x, t.x); result.y = QuantityUtils.min(y, t.y); result.z = QuantityUtils.min(z, t.z); result.a = QuantityUtils.min(a, t.a); result.b = QuantityUtils.min(b, t.b); result.c = QuantityUtils.min(c, t.c); return result; } public void min(Tuple6b a, Tuple6b b){ this.x = QuantityUtils.min(a.x, b.x); this.y = QuantityUtils.min(a.y, b.y); this.z = QuantityUtils.min(a.z, b.z); this.a = QuantityUtils.min(a.a, b.a); this.b = QuantityUtils.min(a.b, b.b); this.c = QuantityUtils.min(a.c, b.c); } public Tuple6b max(Tuple6b t){ Tuple6b result = new Tuple6b(this); result.x = QuantityUtils.max(x, t.x); result.y = QuantityUtils.max(y, t.y); result.z = QuantityUtils.max(z, t.z); result.a = QuantityUtils.max(a, t.a); result.b = QuantityUtils.max(b, t.b); result.c = QuantityUtils.max(c, t.c); return result; } public void max(Tuple6b a, Tuple6b b){ this.x = QuantityUtils.max(a.x, b.x); this.y = QuantityUtils.max(a.y, b.y); this.z = QuantityUtils.max(a.z, b.z); this.a = QuantityUtils.max(a.a, b.a); this.b = QuantityUtils.max(a.b, b.b); this.c = QuantityUtils.max(a.c, b.c); } public Tuple6b subtract(Tuple6b sub){ Tuple6b result = new Tuple6b(this); result.x = QuantityUtils.subtract(x, sub.x); result.y = QuantityUtils.subtract(y, sub.y); result.z = QuantityUtils.subtract(z, sub.z); result.a = QuantityUtils.subtract(a, sub.a); result.b = QuantityUtils.subtract(b, sub.b); result.c = QuantityUtils.subtract(c, sub.c); return result; } public Tuple6b add(Tuple6b sub){ Tuple6b result = new Tuple6b(this); result.x = QuantityUtils.add(x, sub.x); result.y = QuantityUtils.add(y, sub.y); result.z = QuantityUtils.add(z, sub.z); result.a = QuantityUtils.add(a, sub.a); result.b = QuantityUtils.add(b, sub.b); result.c = QuantityUtils.add(c, sub.c); return result; } public Tuple6b scale(int factor){ Tuple6b result = new Tuple6b(this); result.x = QuantityUtils.multiply(x, factor); result.y = QuantityUtils.multiply(y, factor); result.z = QuantityUtils.multiply(z, factor); result.a = QuantityUtils.multiply(a, factor); result.b = QuantityUtils.multiply(b, factor); result.c = QuantityUtils.multiply(c, factor); return result; } public void updateAbsolute(Tuple6b position){ this.x = atomUpdateAbsolute(x, position.x); this.y = atomUpdateAbsolute(y, position.y); this.z = atomUpdateAbsolute(z, position.z); this.a = atomUpdateAbsolute(a, position.a); this.b = atomUpdateAbsolute(b, position.b); this.c = atomUpdateAbsolute(c, position.c); } protected <Q extends Quantity<Q>> Q atomUpdateAbsolute(Q a, Q b) { if( a != null && b!=null){ return b; }else if( a != null){ return a; }else if(b != null){ return b; } return null; } /** * @return the x */ public Length getX() { return x; } /** * @param x the x to set */ public void setX( Length x) { this.x = x; } /** * @return the y */ public Length getY() { return y; } /** * @param y the y to set */ public void setY( Length y) { this.y = y; } /** * @return the z */ public Length getZ() { return z; } /** * @param z the z to set */ public void setZ( Length z) { this.z = z; } /** * @return the a */ public Angle getA() { return a; } /** * @param a the a to set */ public void setA( Angle a) { this.a = a; } /** * @return the b */ public Angle getB() { return b; } /** * @param b the b to set */ public void setB(Angle b) { this.b = b; } /** * @return the c */ public Angle getC() { return c; } /** * @param c the c to set */ public void setC(Angle c) { this.c = c; } public Point3d toPoint3d(Unit<Length> unit){ return new Point3d(getX().value(unit).doubleValue(), getY().value(unit).doubleValue(), getZ().value(unit).doubleValue()); } public Vector3d toVector3d(Unit<Length> unit){ return new Vector3d(getX().value(unit).doubleValue(), getY().value(unit).doubleValue(), getZ().value(unit).doubleValue()); } public Point3d angleToPoint3d(Unit<Angle> unit){ Point3d angle = new Point3d(); if(a != null){ angle.x = a.value(unit).doubleValue(); } if(b != null){ angle.y = b.value(unit).doubleValue(); } if(c != null){ angle.z = c.value(unit).doubleValue(); } return angle; } public Point3f toPoint3f(Unit<Length> unit){ return new Point3f(getX().value(unit).floatValue(), getY().value(unit).floatValue(), getZ().value(unit).floatValue()); } public Tuple6b setNull() { this.x = null; this.y = null; this.z = null; this.a = null; this.b = null; this.c = null; return this; } public Tuple6b to(Unit<Length> unit){ Tuple6b result = new Tuple6b(this); result.setX( getX().to(unit) ); result.setY( getY().to(unit) ); result.setZ( getZ().to(unit) ); return result; } public Tuple6b toAngle(Unit<Angle> unit){ Tuple6b result = new Tuple6b(this); result.setA( getA().to(unit) ); result.setB( getB().to(unit) ); result.setC( getC().to(unit) ); return result; } public Tuple6b setZero() { this.x = Length.ZERO; this.y = Length.ZERO; this.z = Length.ZERO; this.a = Angle.ZERO; this.b = Angle.ZERO; this.c = Angle.ZERO; return this; } public Tuple6b normalize(){ Unit<Length> unit = x.getUnit(); Length pX = this.x.to(unit); Length pY = this.y.to(unit); Length pZ = this.z.to(unit); BigDecimal length = length().value(unit); pX.divide(length); pY.divide(length); pZ.divide(length); return new Tuple6b(pX, pY, pZ, a, b, c); } public Length length(){ BigDecimal bdX = this.x.value(this.x.getUnit()); BigDecimal bdY = this.y.value(this.x.getUnit()); BigDecimal bdZ = this.z.value(this.x.getUnit()); BigDecimal bdx2 = bdX.multiply(bdX); BigDecimal bdy2 = bdY.multiply(bdY); BigDecimal bdz2 = bdZ.multiply(bdZ); return Length.valueOf(BigDecimalUtils.sqrt(bdx2.add(bdy2).add(bdz2),5), this.x.getUnit()); } public Length distance(Tuple6b target){ Unit<Length> unit = target.getX().getUnit(); Length dx = target.getX().subtract(x); Length dy = target.getY().subtract(y); Length dz = target.getZ().subtract(z); BigDecimal dx2 = dx.value(unit).pow(2); BigDecimal dy2 = dy.value(unit).pow(2); BigDecimal dz2 = dz.value(unit).pow(2); BigDecimal result = BigDecimalUtils.sqrt(dx2.add(dy2).add(dz2), dx.value(unit).scale()); return Length.valueOf(result, dx.getUnit()); } /** (inheritDoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((a == null) ? 0 : a.hashCode()); result = prime * result + ((b == null) ? 0 : b.hashCode()); result = prime * result + ((c == null) ? 0 : c.hashCode()); result = prime * result + ((x == null) ? 0 : x.hashCode()); result = prime * result + ((y == null) ? 0 : y.hashCode()); result = prime * result + ((z == null) ? 0 : z.hashCode()); return result; } /** (inheritDoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Tuple6b other = (Tuple6b) obj; if (a == null) { if (other.a != null) { return false; } } else if (!a.equals(other.a)) { return false; } if (b == null) { if (other.b != null) { return false; } } else if (!b.equals(other.b)) { return false; } if (c == null) { if (other.c != null) { return false; } } else if (!c.equals(other.c)) { return false; } if (x == null) { if (other.x != null) { return false; } } else if (!x.equals(other.x)) { return false; } if (y == null) { if (other.y != null) { return false; } } else if (!y.equals(other.y)) { return false; } if (z == null) { if (other.z != null) { return false; } } else if (!z.equals(other.z)) { return false; } return true; } }