|
|
|
package mightypork.utils.math.vect;
|
|
|
|
|
|
|
|
|
|
|
|
import mightypork.utils.annotations.DefaultImpl;
|
|
|
|
import mightypork.utils.annotations.FactoryMethod;
|
|
|
|
import mightypork.utils.math.Calc;
|
|
|
|
import mightypork.utils.math.constraints.VectBound;
|
|
|
|
import mightypork.utils.math.num.Num;
|
|
|
|
import mightypork.utils.math.num.NumConst;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The most basic Vec methods
|
|
|
|
*
|
|
|
|
* @author MightyPork
|
|
|
|
*/
|
|
|
|
public abstract class Vect implements VectBound {
|
|
|
|
|
|
|
|
public static final VectConst ZERO = new VectConst(0, 0, 0);
|
|
|
|
public static final VectConst ONE = new VectConst(1, 1, 1);
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static Vect make(Num xc, Num yc)
|
|
|
|
{
|
|
|
|
return Vect.make(xc, yc, Num.ZERO);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static Vect make(Num xc, Num yc, Num zc)
|
|
|
|
{
|
|
|
|
return new VectNumAdapter(xc, yc, zc);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectConst make(NumConst xc, NumConst yc)
|
|
|
|
{
|
|
|
|
return Vect.make(xc, yc, Num.ZERO);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectConst make(NumConst xc, NumConst yc, NumConst zc)
|
|
|
|
{
|
|
|
|
return new VectConst(xc.value(), yc.value(), zc.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectConst make(double x, double y)
|
|
|
|
{
|
|
|
|
return Vect.make(x, y, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectConst make(double x, double y, double z)
|
|
|
|
{
|
|
|
|
return new VectConst(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectVar makeVar()
|
|
|
|
{
|
|
|
|
return Vect.makeVar(Vect.ZERO);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectVar makeVar(double x, double y)
|
|
|
|
{
|
|
|
|
return Vect.makeVar(x, y, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectVar makeVar(Vect copied)
|
|
|
|
{
|
|
|
|
return Vect.makeVar(copied.x(), copied.y(), copied.z());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@FactoryMethod
|
|
|
|
public static VectVar makeVar(double x, double y, double z)
|
|
|
|
{
|
|
|
|
return new VectVar(x, y, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Num p_size;
|
|
|
|
private Vect p_neg;
|
|
|
|
private Vect p_half;
|
|
|
|
private Vect p_abs;
|
|
|
|
|
|
|
|
private Num p_xc;
|
|
|
|
private Num p_yc;
|
|
|
|
private Num p_zc;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString()
|
|
|
|
{
|
|
|
|
return String.format("(%s,%s,%s)", Calc.toString(x()), Calc.toString(y()), Calc.toString(z()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return X coordinate
|
|
|
|
*/
|
|
|
|
public abstract double x();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Y coordinate
|
|
|
|
*/
|
|
|
|
public abstract double y();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Z coordinate
|
|
|
|
*/
|
|
|
|
@DefaultImpl
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return 0; // implemented for ease with 2D anonymous subtypes
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return X rounded
|
|
|
|
*/
|
|
|
|
public int xi()
|
|
|
|
{
|
|
|
|
return (int) Math.round(x());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Y rounded
|
|
|
|
*/
|
|
|
|
public int yi()
|
|
|
|
{
|
|
|
|
return (int) Math.round(y());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Z rounded
|
|
|
|
*/
|
|
|
|
public int zi()
|
|
|
|
{
|
|
|
|
return (int) Math.round(z());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return X constraint
|
|
|
|
*/
|
|
|
|
public Num xn()
|
|
|
|
{
|
|
|
|
if (p_xc == null) p_xc = new Num() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double value()
|
|
|
|
{
|
|
|
|
return x();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return p_xc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Y constraint
|
|
|
|
*/
|
|
|
|
public Num yn()
|
|
|
|
{
|
|
|
|
if (p_yc == null) p_yc = new Num() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double value()
|
|
|
|
{
|
|
|
|
return y();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return p_yc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Z constraint
|
|
|
|
*/
|
|
|
|
public Num zn()
|
|
|
|
{
|
|
|
|
if (p_zc == null) p_zc = new Num() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double value()
|
|
|
|
{
|
|
|
|
return z();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return p_zc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public final Vect getVect()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if zero
|
|
|
|
*/
|
|
|
|
public boolean isZero()
|
|
|
|
{
|
|
|
|
return x() == 0 && y() == 0 && z() == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a static immutable copy of the current state.
|
|
|
|
*
|
|
|
|
* @return a immutable copy
|
|
|
|
*/
|
|
|
|
public VectConst freeze()
|
|
|
|
{
|
|
|
|
return new VectConst(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a view with X set to given value
|
|
|
|
*
|
|
|
|
* @param x x coordinate
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect withX(double x)
|
|
|
|
{
|
|
|
|
return withX(Num.make(x));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a view with Y set to given value
|
|
|
|
*
|
|
|
|
* @param y y coordinate
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect withY(double y)
|
|
|
|
{
|
|
|
|
return withY(Num.make(y));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a view with Z set to given value
|
|
|
|
*
|
|
|
|
* @param z z coordinate
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect withZ(double z)
|
|
|
|
{
|
|
|
|
return withZ(Num.make(z));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect withX(final Num x)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return x.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.z();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect withY(final Num y)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return y.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect withZ(final Num z)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.y();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return z.value();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get absolute value (positive)
|
|
|
|
*
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect abs()
|
|
|
|
{
|
|
|
|
if (p_abs == null) p_abs = new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return Math.abs(t.x());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return Math.abs(t.y());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return Math.abs(t.z());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return p_abs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a vector.
|
|
|
|
*
|
|
|
|
* @param vec offset
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect add(Vect vec)
|
|
|
|
{
|
|
|
|
return add(vec.xn(), vec.yn(), vec.zn());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add to each component.<br>
|
|
|
|
* Z is unchanged.
|
|
|
|
*
|
|
|
|
* @param x x offset
|
|
|
|
* @param y y offset
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect add(double x, double y)
|
|
|
|
{
|
|
|
|
return add(x, y, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add to each component.
|
|
|
|
*
|
|
|
|
* @param x x offset
|
|
|
|
* @param y y offset
|
|
|
|
* @param z z offset
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect add(final double x, final double y, final double z)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x() + x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.y() + y;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z() + z;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect add(Num x, Num y)
|
|
|
|
{
|
|
|
|
return add(x, y, Num.ZERO);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect add(final Num x, final Num y, final Num z)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x() + x.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.y() + y.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z() + z.value();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get copy divided by two
|
|
|
|
*
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect half()
|
|
|
|
{
|
|
|
|
if (p_half == null) p_half = mul(0.5);
|
|
|
|
return p_half;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.
|
|
|
|
*
|
|
|
|
* @param d multiplier
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(double d)
|
|
|
|
{
|
|
|
|
return mul(d, d, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.
|
|
|
|
*
|
|
|
|
* @param vec vector of multipliers
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(Vect vec)
|
|
|
|
{
|
|
|
|
return mul(vec.xn(), vec.yn(), vec.zn());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.<br>
|
|
|
|
* Z is unchanged.
|
|
|
|
*
|
|
|
|
* @param x x multiplier
|
|
|
|
* @param y y multiplier
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(double x, double y)
|
|
|
|
{
|
|
|
|
return mul(x, y, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.
|
|
|
|
*
|
|
|
|
* @param x x multiplier
|
|
|
|
* @param y y multiplier
|
|
|
|
* @param z z multiplier
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(final double x, final double y, final double z)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x() * x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.y() * y;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z() * z;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.
|
|
|
|
*
|
|
|
|
* @param d multiplier
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(final Num d)
|
|
|
|
{
|
|
|
|
return mul(d, d, d);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.
|
|
|
|
*
|
|
|
|
* @param x x multiplier
|
|
|
|
* @param y y multiplier
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(final Num x, final Num y)
|
|
|
|
{
|
|
|
|
return mul(x, y, Num.ONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply each component.
|
|
|
|
*
|
|
|
|
* @param x x multiplier
|
|
|
|
* @param y y multiplier
|
|
|
|
* @param z z multiplier
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect mul(final Num x, final Num y, final Num z)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x() * x.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.y() * y.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z() * z.value();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Round coordinates.
|
|
|
|
*
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect round()
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return Math.round(t.x());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return Math.round(t.y());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return Math.round(t.z());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Round coordinates down.
|
|
|
|
*
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect floor()
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return Math.floor(t.x());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return Math.floor(t.y());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return Math.floor(t.z());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Round coordinates up.
|
|
|
|
*
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect ceil()
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return Math.ceil(t.x());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return Math.ceil(t.y());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return Math.ceil(t.z());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subtract vector.
|
|
|
|
*
|
|
|
|
* @param vec offset
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect sub(Vect vec)
|
|
|
|
{
|
|
|
|
return sub(vec.xn(), vec.yn(), vec.zn());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subtract a 2D vector.<br>
|
|
|
|
* Z is unchanged.
|
|
|
|
*
|
|
|
|
* @param x x offset
|
|
|
|
* @param y y offset
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect sub(double x, double y)
|
|
|
|
{
|
|
|
|
return add(-x, -y, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subtract a 3D vector.
|
|
|
|
*
|
|
|
|
* @param x x offset
|
|
|
|
* @param y y offset
|
|
|
|
* @param z z offset
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect sub(double x, double y, double z)
|
|
|
|
{
|
|
|
|
return add(-x, -y, -z);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect sub(Num x, Num y)
|
|
|
|
{
|
|
|
|
return sub(x, y, Num.ZERO);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect sub(final Num x, final Num y, final Num z)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.x() - x.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.y() - y.value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.z() - z.value();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Negate all coordinates (* -1)
|
|
|
|
*
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect neg()
|
|
|
|
{
|
|
|
|
if (p_neg == null) p_neg = mul(-1);
|
|
|
|
return p_neg;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Scale vector to given size.
|
|
|
|
*
|
|
|
|
* @param size size we need
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect norm(final Num size)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
final double tSize = t.size().value();
|
|
|
|
final double nSize = size.value();
|
|
|
|
|
|
|
|
if (tSize == 0 || nSize == 0) return 0;
|
|
|
|
|
|
|
|
return x() / (nSize / tSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
final double tSize = t.size().value();
|
|
|
|
final double nSize = size.value();
|
|
|
|
|
|
|
|
if (tSize == 0 || nSize == 0) return 0;
|
|
|
|
|
|
|
|
return y() / (nSize / tSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
final double tSize = t.size().value();
|
|
|
|
final double nSize = size.value();
|
|
|
|
|
|
|
|
if (tSize == 0 || nSize == 0) return 0;
|
|
|
|
|
|
|
|
return z() / (nSize / tSize);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Vect norm(final double size)
|
|
|
|
{
|
|
|
|
return norm(Num.make(size));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get distance to other point
|
|
|
|
*
|
|
|
|
* @param point other point
|
|
|
|
* @return distance
|
|
|
|
*/
|
|
|
|
public Num dist(final Vect point)
|
|
|
|
{
|
|
|
|
return new Num() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double value()
|
|
|
|
{
|
|
|
|
final double dx = t.x() - point.x();
|
|
|
|
final double dy = t.y() - point.y();
|
|
|
|
final double dz = t.z() - point.z();
|
|
|
|
|
|
|
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get middle of line to other point
|
|
|
|
*
|
|
|
|
* @param point other point
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect midTo(final Vect point)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return (point.x() + t.x()) * 0.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return (point.y() + t.y()) * 0.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return (point.z() + t.z()) * 0.5;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create vector from this point to other point
|
|
|
|
*
|
|
|
|
* @param point second point
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public Vect vectTo(final Vect point)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return (point.x() - t.x());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return (point.y() - t.y());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return (point.z() - t.z());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get cross product (vector multiplication)
|
|
|
|
*
|
|
|
|
* @param vec other vector
|
|
|
|
* @return result
|
|
|
|
*/
|
|
|
|
public final Vect cross(final Vect vec)
|
|
|
|
{
|
|
|
|
return new Vect() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double x()
|
|
|
|
{
|
|
|
|
return t.y() * vec.z() - t.z() * vec.y();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double y()
|
|
|
|
{
|
|
|
|
return t.z() * vec.x() - t.x() * vec.z();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double z()
|
|
|
|
{
|
|
|
|
return t.x() * vec.y() - t.y() * vec.x();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get dot product (scalar multiplication)
|
|
|
|
*
|
|
|
|
* @param vec other vector
|
|
|
|
* @return dot product
|
|
|
|
*/
|
|
|
|
public Num dot(final Vect vec)
|
|
|
|
{
|
|
|
|
return new Num() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double value()
|
|
|
|
{
|
|
|
|
return t.x() * vec.x() + t.y() * vec.y() + t.z() * vec.z();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get vector size
|
|
|
|
*
|
|
|
|
* @return size
|
|
|
|
*/
|
|
|
|
public Num size()
|
|
|
|
{
|
|
|
|
if (p_size == null) p_size = new Num() {
|
|
|
|
|
|
|
|
final Vect t = Vect.this;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public double value()
|
|
|
|
{
|
|
|
|
final double x = t.x(), y = t.y(), z = t.z();
|
|
|
|
return Math.sqrt(x * x + y * y + z * z);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return p_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode()
|
|
|
|
{
|
|
|
|
final int prime = 31;
|
|
|
|
int result = 1;
|
|
|
|
result = prime * result + Double.valueOf(x()).hashCode();
|
|
|
|
result = prime * result + Double.valueOf(y()).hashCode();
|
|
|
|
result = prime * result + Double.valueOf(z()).hashCode();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj)
|
|
|
|
{
|
|
|
|
if (this == obj) return true;
|
|
|
|
if (obj == null) return false;
|
|
|
|
if (!(obj instanceof Vect)) return false;
|
|
|
|
final Vect other = (Vect) obj;
|
|
|
|
|
|
|
|
return x() == other.x() && y() == other.y() && z() == other.z();
|
|
|
|
}
|
|
|
|
}
|