// SPoint: a 3D point on the surface of a sphere.

import java.text.DecimalFormat;

class SPoint {
	public double[] p   = new double[3]; // coordinates of point
	public double[] vel = new double[3]; // velocity vector
	public double[] acc = new double[3]; // acceleration vector
	public double velMag;		// magnitude of velocity

	public SPoint(double x, double y, double z) {
		p[0] = x;
		p[1] = y;
		p[2] = z;
	}

	// copy contents of vector from[] to to[].
	public static void copyVec(double[] from, double[] to) {
		to[0] = from[0];
		to[1] = from[1];
		to[2] = from[2];
	}

	// Normalize vector, i.e. scale it to unit length.
	// Return the former length of the vector.
	public static double normalize(double[] p) {
		double len = mag(p);
		if (len == 0) // throw exception?
			return 0;
		double scale = 1.0/len;
		p[0] *= scale;
		p[1] *= scale;
		p[2] *= scale;
		return len;
	}

	// Magnitude (length) of vector
	public static double mag(double q[]) {
		return Math.sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2]);
	}

	// Dot product of two vectors
	public static double dotProd(double q[], double r[]) {
		return (q[0]*r[0] + q[1]*r[1] + q[2]*r[2]);
	}

	double[] tmpf = new double[3];

	// Transform vector p by matrix m; if veloc, then also transform vel.
	public void transform(Matrix m, boolean veloc) {
		m.transform(p, tmpf);
		copyVec(tmpf, p);
		if (veloc) {
			m.transform(vel, tmpf);
			copyVec(tmpf, vel);
		}
	}
	
	// Set vector s to cross-product of q and r.
	// s cannot be the same object as q or r.
	public static void cross(double[] q, double[] r, double[] s) {
		s[0] = q[1]*r[2] - q[2]*r[1];
		s[1] = q[2]*r[0] - q[0]*r[2];
		s[2] = q[0]*r[1] - q[1]*r[0];
	}
	
	// Subtract r from q, putting result in s.
	public static void subtract3(double[] q, double[] r, double[] s) {
		s[0] = q[0] - r[0];
		s[1] = q[1] - r[1];
		s[2] = q[2] - r[2];
	}

	// q -= r.
	public static void subtract(double[] q, double[] r) {
		q[0] -= r[0];
		q[1] -= r[1];
		q[2] -= r[2];
	}

	// q += r.
	public static void add(double[] q, double[] r) {
		q[0] += r[0];
		q[1] += r[1];
		q[2] += r[2];
	}

	// q *= coeff.
	public static void scale(double[] q, double coeff) {
		q[0] *= coeff;
		q[1] *= coeff;
		q[2] *= coeff;
	}

	public String toString() {
		DecimalFormat df = new DecimalFormat("0.###");
		return "p<" + df.format(p[0]) + ", " + df.format(p[1]) + ", " +
			df.format(p[2]) +
			"> vel<" + df.format(vel[0]) + ", " +
			df.format(vel[1]) + ", " + df.format(vel[2])  +
			"> velMag " + df.format(velMag);
	}
}
