package real;

/* Copyright 1997 Bill Casselman
   University of British Columbia
   cass@math.ubc.ca */
   
import real.Real2DVector;

public class RealPoint {
	public double x, y;

	public RealPoint(double a, double b) {
		x = a;
		y = b;
	}

	public String toString() {
		return("(" + Real.toString(x) + ", " + Real.toString(y) + ")");
	}
	
	public void translate(double a, double b) {
		x += a;
		y += b;
	}
	
	public RealPoint translatedBy(double a, double b) {
		return(new RealPoint(x + a, y + b));
	}
	
	public RealPoint translatedBy(Real2DVector v) {
		return(new RealPoint(x + v.x, y + v.y));
	}
	
	public RealPoint plus(Real2DVector v) {
		return(new RealPoint(x + v.x, y + v.y));
	}
	
	public RealPoint minus(Real2DVector v) {
		return(new RealPoint(x - v.x, y - v.y));
	}
	
	public Real2DVector minus(RealPoint P) {
		return(new Real2DVector(x - P.x, y - P.y));
	}
	
	public void scale(double c) {
		x *= c;
		y *= c;
	}
	
	public RealPoint transformedBy(double m[][]) {
		double a, b;
		a = m[0][0]*x + m[0][1]*y;
		b = m[1][0]*x + m[1][1]*y;
		return(new RealPoint(a, b));
	}
	
	// [c -s | s c] [x y] 
	public RealPoint rotated(double theta) {
		double c, s;
		c = Math.cos(theta);
		s = Math.sin(theta);
		RealPoint Q = new RealPoint(c*x - s*y, s*x + c*y);
		return(Q);
	}

	public RealPoint interp(double t, RealPoint P) {
		RealPoint Q = new RealPoint((1.0 - t)*x + t*P.x, (1.0 - t)*y + t*P.y);
		return(Q);
	}
	
	public static RealPoint interpolate(double t, RealPoint Q, RealPoint P) {
		RealPoint R = new RealPoint((1 - t)*Q.x + t*P.x, (1 - t)*Q.y + t*P.y);
		return(R);
	}
	
	public RealPoint interpolate(double t, RealPoint P) {
		RealPoint R = new RealPoint((1 - t)*x + t*P.x, (1 - t)*y + t*P.y);
		return(R);
	}
	
	public void normalize() {
		double R = Math.sqrt(x*x + y*y);
		x /= R;
		y /= R;
	}

	public void normalize(double c) {
		double R = Math.sqrt(x*x + y*y);
		c /= R;
		x *= c;
		y *= c;
	}

	public RealPoint normalized(double c) {
		double R = Math.sqrt(x*x + y*y);
		c /= R;
		double X = c*x;
		double Y = c*y;
		return(new RealPoint(X, Y));
	}
	public RealPoint normalized() {
		double R = Math.sqrt(x*x + y*y);
		double X = x/R;
		double Y = y/R;
		return(new RealPoint(X, Y));
	}
	
	public static double distance(RealPoint t, RealPoint h) {
		double r;
		double x = h.x - t.x, y = h.y - t.y;
		double X = Math.abs(x), Y = Math.abs(y);
		if (X > Y) {
			r = X*Math.sqrt(1 + (Y/X)*(Y/X));
		} else {
			r = Y*Math.sqrt(1 + (X/Y)*(X/Y));
		}
		return(r);
	}
	
	public double distanceTo(RealPoint Q) {
		double X = Math.abs(x - Q.x), Y = Math.abs(y - Q.y);
		double r;
		if (X > Y) {
			r = X*Math.sqrt(1 + (Y/X)*(Y/X));
		} else {
			r = Y*Math.sqrt(1 + (X/Y)*(X/Y));
		}
		return(r);
	}
	
	
}

