import java.awt.*;
import java.awt.image.*;


public class Vector3D{
  
  private float v[];
  protected int vecSize = 3;
    //protected int size = 4;
  protected float vMag;
  

  ///////////////////////// CONSTRUCTORS ///////////////////
  
  /**
   *  This constructor, which takes no arguments,
   *  allows for future extension.
   */
  public Vector3D() {
    v = new float[vecSize];
    loadNull();
  }
  
  /**
    initialize components
   */
  public Vector3D( float vx, float vy, float vz) {
    v = new float[vecSize];
    v[0]=vx; v[1]=vy; v[2]=vz;
    vMag = (float) Math.sqrt( v[0]*v[0] +  v[1]*v[1] +  v[2]*v[2] );
  }
  
 
  
  ////////////////////////// METHODS //////////////////// 

  public final void loadNull( ) {
    for( int i=0; i<vecSize; i++){
	  v[i] = 0.0f;
    }
    vMag = 0.0f;
    return;
  }

  public final void loadNull(float[] ary) {
    for( int i=0; i<vecSize; i++){
      for(int j=0; j<vecSize; j++){
	  ary[index(i,j)] = 0.0f;
      }
      return;
    }
  }
  
  /**
   *  Returns the components
   */
  public final float getV( int i ) {
    return v[i];
  }
  public final float getVx( ) {
    return v[0];
  }
    public final float getVy( ) {
    return v[1];
  }
    public final float getVz( ) {
    return v[2];
  }
  
    public final float getMag( ) {
    return vMag;
  }
  
  /**
   *  Sets the components
   */
  public final void setV( int i, float val ) {
    v[i] = val;
  }

  public void normalize(){
    if( vMag!=0) {
      for( int i=0; i<vecSize; i++) v[i] = v[i]/ vMag;
    }
    return;
  }

  public void symmetrify( float[] symMat ) {
    loadNull( symMat );
    //symMat[ index(size-1, size-1) ] = 1.0f;
    for( int i=0; i<vecSize; i++ ){
      for( int j=0; j<vecSize; j++ ){
	symMat[ index(i,j) ] = v[i]*v[j];
      } 
    } 
    return;
  }

   public void skewify( float[] skewMat ) {
    loadNull( skewMat );
    //skewMat[ index(size-1, size-1) ] = 1.0f;
    skewMat[ index(0,1) ] = -v[2];
    skewMat[ index(1,0) ] = v[2];
    skewMat[ index(0,2) ] = v[1];
    skewMat[ index(2,0) ] = -v[1];
    skewMat[ index(1,2) ] = -v[0];
    skewMat[ index(2,1) ] = v[0];
    return;
  }
 
   public void crossProd( Vector3D vec, Vector3D res ) {
     res.setV( 0,  this.v[1]*vec.getV(2) - this.v[2]*vec.getV(1) );
     res.setV( 1,  this.v[2]*vec.getV(0) - this.v[0]*vec.getV(2) );
     res.setV( 2,  this.v[0]*vec.getV(1) - this.v[1]*vec.getV(0) );
     return;
   }

   public float dotProd( Vector3D vec ) {
     return( this.v[0]*vec.getV(0) + this.v[1]*vec.getV(1) + this.v[2]*vec.getV(2) );
   }

   private int index(int i, int j) {
     return( i*vecSize+j );
   }

  public final void scalarMul( float[] mat, float k) {
    for( int i=0; i< vecSize; i++){
      for( int j=0; j< vecSize; j++){
	mat[ index(i,j) ] *= k;
      }
    }   
  }

 public final void setToIdentity(float[] ary) {
    for( int i=0; i<vecSize; i++){
      for(int j=0; j<vecSize; j++){
	if(i==j)
	  ary[index(i,j)] = 1.0f;
	else
	  ary[index(i,j)] = 0.0f;
      }
    }
  }

 public final void matAdd( float[] mat1, float[] mat2) {
    for( int i=0; i< vecSize; i++){
      for( int j=0; j< vecSize; j++){
	mat1[ index(i,j) ] += mat2[ index(i,j) ];
      }
    }   
  }


} //VECTOR3D

