import java.awt.event.*;
import java.awt.*;

/*This class does the basic arithmetic
  of vectors */


public class Vector {
    double[] x=new double[3];
    public Vector(){}

    public Vector(Complex z) {
	x[0]=z.x;
	x[1]=z.y;
	x[2]=1.0;
    }

    public Vector(double xx,double yy) {
	x[0]=xx;
	x[1]=yy;
	x[2]=1.0;
    }

    public Vector(double xx,double yy,double zz) {
	x[0]=xx;
	x[1]=yy;
	x[2]=zz;
    }

    public Vector(Vector X) {
	x[0]=X.x[0];
	x[1]=X.x[1];
	x[2]=X.x[2];
    }

    public static double dist(Vector V1,Vector V2) {
	Vector W1=V1.normalize();
	Vector W2=V2.normalize();
	double xx=W1.x[0]-W2.x[0];
	double yy=W1.x[1]-W2.x[1];
	double d=xx*xx+yy*yy;
	d=Math.sqrt(d);
	return(d);
    }


    public int between(Vector V1,Vector V2,Vector V3) {
	double d1=dist(V1,V2);
	double d2=dist(V2,V3);
	double d3=dist(V1,V3);
	if(d1+d2-d3<.00000000001) return(1);
	return(0);
    }


    public Vector pullback(Complex z) {
	Vector V=new Vector();
	V.x[0]=x[0]-z.x;
	V.x[1]=x[1]-z.y;
	V.x[2]=1.0;
	return(V);
    }


    public static double  dot(Vector v,Vector w) {
	return(v.x[0]*w.x[0]+v.x[1]*w.x[1]+v.x[2]*w.x[2]);
    }




    public double norm() {
	return(Math.sqrt(dot(this,this)));
    }





    public static Vector cross(Vector v,Vector w) {
	Vector X=new Vector();
	X.x[0]=v.x[1]*w.x[2]-w.x[1]*v.x[2];
	X.x[1]=v.x[2]*w.x[0]-w.x[2]*v.x[0];
	X.x[2]=v.x[0]*w.x[1]-w.x[0]*v.x[1];
	return(X);
    }

    public void print() {
	System.out.println(x[0]+" "+x[1]+" "+x[2]);
    }


    public Vector normalize() {
	Vector W=new Vector();
	W.x[0]=this.x[0]/this.x[2];
	W.x[1]=this.x[1]/this.x[2];
	W.x[2]=1;
	return(W);
    }

    public Vector unitize() {
	Vector V=this.normalize();
	double d=V.x[0]*V.x[0]+V.x[1]*V.x[1];
	d=Math.sqrt(d);
	V.x[0]=V.x[0]/d;
	V.x[1]=V.x[1]/d;
	return(V);
    }

    public Vector unitSphere() {
	Vector V=new Vector(this);
	double d=Math.sqrt(dot(V,V));
	d=Math.sqrt(d);
	V.x[0]=V.x[0]/d;
	V.x[1]=V.x[1]/d;
	V.x[2]=V.x[2]/d;
	return(V);
    }



    public static double tripleProduct(Vector v1,Vector v2,Vector v3) {
	return(dot(cross(v1,v2),v3));
    }

    public static double tripleProduct2(Complex z1,Complex z2,Complex z3) {
	Vector v1=new Vector(z1);
	Vector v2=new Vector(z2);
	Vector v3=new Vector(z3);
	return(tripleProduct(v1,v2,v3));
    }



    public Complex  toComplex() {
	return(new Complex(x[0]/x[2],x[1]/x[2]));
    }

    public static Vector findCross(Vector v1,Vector v2,Vector v3,Vector v4) {
	Vector v5=cross(v1,v2);
	Vector v6=cross(v3,v4);
	Vector v7=cross(v5,v6);
	return(v7);
    }

    public static Complex findCross2(Complex z1,Complex z2,Complex z3,Complex z4) {
	Vector v1=new Vector(z1);
	Vector v2=new Vector(z2);
	Vector v3=new Vector(z3);	
        Vector v4=new Vector(z4);
	Vector v5=findCross(v1,v2,v3,v4);
	return(v5.toComplex());
    }



    //returns a normalized vector

    public Vector rotate(double d) {

	Vector V1=this.normalize();
	double c=Math.cos(d);
	double s=Math.sin(d);
	double x0=V1.x[0];
	double x1=V1.x[1];
	double y0= x0*c+x1*s;
	double y1=-x0*s+x1*c;
	V1.x[0]=y0;
	V1.x[1]=y1;
	V1.x[2]=1.0;
	return(V1);
    }


    /*w and h are width and height of inner ellipse.  
      The outer ellipse is unit circle.*/

    Vector nextPoncelet(double w,double h) {
	Vector W=new Vector();
	double x1=this.x[0]/this.x[2];
	double y1=this.x[1]/this.x[2];
	double c=(x1/w)*(x1/w)+(y1/h)*(y1/h);
	double t=Math.sqrt(c-1);
	double x2=(w*t*y1/h+x1)/c;
	double y2=(y1-h*t*x1/w)/c;
	double vx=y2-y1;
	double vy=x1-x2;
	double d=Math.sqrt(vx*vx+vy*vy);
	double ux=vx/d;
	double uy=vy/d;
	d=x1*ux+y1*uy;
	W.x[0]=-x1+2*d*ux;
        W.x[1]=-y1+2*d*uy;
	W.x[2]=1;
	return(W);
    }


    public static double angle(Vector V,Vector W) {
	double t1=dot2(V,W);
	double t2=dot2(V,V);
	double t3=dot2(W,W);
	double t4=t1/Math.sqrt(t2*t3);
	double a=Math.acos(t4);
	return(a);
    }


    public static double  dot2(Vector v,Vector w) {
	Vector V=v.normalize();
	Vector W=w.normalize();
	return(V.x[0]*W.x[0]+V.x[1]*W.x[1]);
    }

    public Vector matrixAct(double[][] y) {
	Vector X=this.normalize();
	Vector Y=new Vector();
	Y.x[0]=y[0][0]*X.x[0]+y[0][1]*X.x[1];
	Y.x[1]=y[1][0]*X.x[0]+y[1][1]*X.x[1];
	Y.x[2]=1;
	return(Y);
    }


}




