package actor;
import java.text.DecimalFormat;
import render.Matrix;
public class Point3D implements Cloneable
{
public double x,y,z;
public Point3D()
{
this.x=0d;
this.y=0d;
this.z=0d;
}
public Point3D(double x, double y, double z)
{
this.x=x;
this.y=y;
this.z=z;
}
public Point3D(Point3D src)
{
this.x=src.x;
this.y=src.y;
this.z=src.z;
}
public Point3D set(double x, double y, double z)
{
this.x=x;
this.y=y;
this.z=z;
return this;
}
public Point3D setX(double x)
{
this.x = x;
return this;
}
public Point3D setY(double y)
{
this.y = y;
return this;
}
public Point3D setZ(double z)
{
this.z = z;
return this;
}
public static double distance2D(Point3D a, Point3D b)
{
double X1 = a.x;
double Y1 = a.y;
X1 -= b.x; Y1 -= b.y;
return Math.sqrt(X1 * X1 + Y1 * Y1);
}
public double distance2D(Point3D a)
{
double X1 = a.x;
double Y1 = a.y;
X1 -= this.x; Y1 -= this.y;
return Math.sqrt(X1 * X1 + Y1 * Y1);
}
public static double dot(Point3D thisVec, Point3D otherVec)
{
double sum = 0;
sum += thisVec.x * otherVec.x;
sum += thisVec.y * otherVec.y;
sum += thisVec.z * otherVec.z;
return sum;
}
public double dot(Point3D otherVec)
{
double sum = 0;
sum += x * otherVec.x;
sum += y * otherVec.y;
sum += z * otherVec.z;
return sum;
}
public double norm()
{
return Math.sqrt(dot(this));
}
public Point3D normalize()
{
double s = norm();
if (s==0) return this;
this.x /= s;
this.y /= s;
this.z /= s;
return this;
}
public static Point3D cross(Point3D thisVec, Point3D otherVec)
{
Point3D answer = new Point3D(0,0,0);
answer.x = otherVec.y * thisVec.z - otherVec.z * thisVec.y;
answer.y = otherVec.z * thisVec.x - otherVec.x * thisVec.z;
answer.z = otherVec.x * thisVec.y - otherVec.y * thisVec.x;
return answer;
}
public Point3D cross(Point3D otherVec)
{
this.x = otherVec.y * this.z - otherVec.z * this.y;
this.y = otherVec.z * this.x - otherVec.x * this.z;
this.z = otherVec.x * this.y - otherVec.y * this.x;
return this;
}
public Point3D add(Point3D other)
{
this.add(other.getX(), other.getY(), other.getZ());
return this;
}
public Point3D subtract(Point3D other)
{
this.add(-other.getX(), -other.getY(), -other.getZ());
return this;
}
public static Point3D subtract(Point3D one, Point3D other)
{
return new Point3D(-other.getX(), -other.getY(), -other.getZ()).add(one);
}
public double[] toArray()
{
return new double[] { x,y,z };
}
public double getX() { return x; }
public double getY() { return y; }
public double getZ() { return z; }
public Point3D add(double xa, double ya, double za)
{
this.x += xa ;
this.y += ya ;
this.z += za ;
return this;
}
public Point3D multiply(double d)
{
this.x *= d;
this.y *= d;
this.z *= d;
return this;
}
public static Point3D add(Point3D a, Point3D b)
{
return new Point3D(a).add(b);
}
public static Point3D multiply(double d, Point3D p)
{
return new Point3D(p.x * d, p.y *d, p.z * d);
}
public static Point3D lerp(double t, Point3D a, Point3D b)
{
return lerp(t, a, b, new Point3D());
}
public static Point3D lerp(double t, Point3D a, Point3D b, Point3D dst)
{
dst.x = lerp(t, a.x, b.x);
dst.y = lerp(t, a.y, b.y);
dst.z = lerp(t, a.z, b.z);
return dst;
}
public static double lerp(double t, double a, double b)
{
return a + t * (b - a);
}
public static Point3D[] transformPoints(Matrix m, Point3D[] pts)
{
Point3D[] returnPts = new Point3D[pts.length];
for(int i = 0; i < pts.length; i++)
returnPts[i] = Point3D.matrixTransform(m, pts[i]);
return returnPts;
}
public static Point3D matrixTransform(Matrix m, Point3D p)
{
double[] v = new double[4];
transformVertex(m, p.x, p.y, p.z, 1, v);
return new Point3D(v[0], v[1], v[2]);
}
public static Point3D matrixTransform(Matrix m, double x, double y, double z)
{
double[] v = new double[4];
transformVertex(m, x, y, z, 1, v);
return new Point3D(v[0], v[1], v[2]);
}
public static Point3D createDirectionVector(Matrix rotationMatrix)
{
return matrixTransform(rotationMatrix, 0, 0, 1);
}
private static double[] transformVertex(
Matrix m,
double x,
double y,
double z,
double w,
double[] v)
{
if (w == 0)
for (int j = 0; j < 3; j++)
v[j] = m.get(j, 0) * x + m.get(j, 1) * y + m.get(j, 2) * z;
else
for (int j = 0; j < 3; j++)
v[j] =
m.get(j, 0) * x + m.get(j, 1) * y + m.get(j, 2) * z + m.get(j, 3);
return v;
}
public double getXRotation()
{
Point3D YZPlaneVector = new Point3D(0.0, y, z).normalize();
double derivedRotationAngle = Math.atan2(YZPlaneVector.y, YZPlaneVector.z);
if(YZPlaneVector.y < 0)
derivedRotationAngle = (2*Math.PI) + derivedRotationAngle;
return(derivedRotationAngle);
}
public double getYRotation()
{
Point3D XZPlaneVector = new Point3D(x, 0.0, z).normalize();
double derivedRotationAngle = Math.atan2(XZPlaneVector.x, XZPlaneVector.z);
if(XZPlaneVector.x < 0)
derivedRotationAngle = (2*Math.PI) + derivedRotationAngle;
return(derivedRotationAngle);
}
public double getZRotation()
{
Point3D XYPlaneVector = new Point3D(x, y, 0.0).normalize();
double derivedRotationAngle = Math.atan2(XYPlaneVector.x, XYPlaneVector.y);
if(XYPlaneVector.x < 0)
derivedRotationAngle = (2*Math.PI) + derivedRotationAngle;
return(derivedRotationAngle);
}
public Object clone()
{
Object o = null;
try
{
o = super.clone();
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return o;
}
private static DecimalFormat dF = new DecimalFormat("+0.000;-0.000");
public String toString()
{
return (
"["
+ dF.format(getX())
+ ","
+ dF.format(getY())
+ ","
+ dF.format(getZ())
+ "]");
}
}