package SModeling;


/**
 *  Represents a point with homogeneous coordinates (x',y',z',w).
 *  x = x'/w, y = y'/w, z = z'/w.<p>
 *  
 * <hr>
 * Copyright (c) 1995, H. Robert Frost, Stanford University.
 * All rights reserved.<p>
 * Copyright (c) 1996, H. Robert Frost, Enterprise Integration Technologies,
 * Inc. All rights reserved.<p>
 *
 * RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by the 
 * Government is subject to restrictions as set forth in 
 * subparagraph(c)(1)(ii) of the Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 and in similar clauses in the
 * FAR and NASA FAR supplement.<p>
 * 
 * This software is bound by the terms and conditions listed in the
 * attached <a href="../LICENSE">LICENSE file</A>.
 * <hr>
 * @author <A HREF="http://cdr.stanford.edu/html/people/frost-bio.html"> Rob Frost</A>
 * @version 5/21/96 for Java(tm) Language Version 1.0.2
 */

public class hpoint implements Cloneable {
 
  float xprime, yprime, zprime, w;
  
  /**
   * Creates an hpoint initialized to the origin (0,0,0,1).
   */
  public hpoint () {
    xprime = 0;
    yprime = 0;
    zprime = 0;
    w = 1;
  }

  /**
   * Creates an hpoint at the specified x,y and z coordinates.
   * @param a x' value
   * @param b y' value
   * @param c z' value
   * @param d w value
   */

  public hpoint (float a, float b, float c, float d) {
    xprime = a;
    yprime = b;
    zprime = c;
    w = d;
  }

  /**	
   * Allows the object to be cloned. Must cast to appropriate
   * object type.
   * @return Copy of the object.
   */
  
  public Object clone() {
    Object result = null;
    try{
      result = super.clone();
      return result;
    } catch (CloneNotSupportedException e){}
    return result;
  } 

  /**
   * Returns the x value of the hpoint.
   * @return Floating point value of x coordinate.
   */
  
  public float getx() {
    return xprime/w;
  }

  /**
   * Returns the x value of the hpoint.
   * @return Floating point value of x coordinate.
   */

  public float gety() {
    return yprime/w;
  }

  /**
   * Returns the x value of the hpoint.
   * @return Floating point value of x coordinate.
   */

  public float getz() {
    return zprime/w;
  }

  /**
   * Computes the inner product of the current point and the specified point.
   * @param hp hpoint to dot with current point.
   * @return Floating point result
   */
  public float dot(hpoint hp) {
    return (this.getx()*hp.getx() +
	    this.gety()*hp.gety() +
	    this.getz()*hp.getz());
  }

  /**
   * Computes the cross product of the current point and the specified point.
   * Replaces the current point with the result. (this X hp)
   * @param hp hpoint to cross with current hpoint
   */
  public void cross(hpoint hp) {
    float x,y,z;
   
    x = gety()*hp.getz() - getz()*hp.gety();
    y = -getx()*hp.getz() + getz()*hp.getx();
    z = getx()*hp.gety() - gety()*hp.getx();
    xprime = x*w;
    yprime = y*w;
    zprime = z*w;
  }
 
  /**
   * Normalizes the current point (scales to unit length).
   */

  public void normalize() {
    float x = getx();
    float y = gety();
    float z = getz();
    double t = Math.sqrt(x*x + y*y + z*z);
    xprime = w*(x/(float)t);
    yprime = w*(y/(float)t);
    zprime = w*(z/(float)t);
  }
	
  /**
   * Computes the scalar length of the point.
   * @return Floating point magnitude.
   */

  public float magnitude() {
    float x = getx();
    float y = gety();
    float z = getz();
    return(x*x + y*y + z*z);
  }

  /**
   * Computes the vector difference of the current point and the specified 
   * point. Returns the result. (this - p)
   * @param p hpoint to substract
   * @return hpoint result
   */

  public hpoint diff(hpoint p){
	float x,y,z;
	hpoint temp = new hpoint(getx()-p.getx(),
				 gety()-p.gety(),
				 getz()-p.getz(), 1);
	return temp;
  }

  /**
   * Computes the vector sum of the current point and the specified 
   * point. Returns the result. (this + p)
   * @param p hpoint to add
   * @return hpoint result
   */
  
  public hpoint add(hpoint p) {
    float x,y,z;
	hpoint temp = new hpoint(getx()+p.getx(),
				 gety()+p.gety(),
				 getz()+p.getz(), 1);
	return temp;
  }

  /**
   * Scales the current point the specified factor (w = w/factor).
   * @param factor scaling factor
   */

  public void scale(float factor) {
    w = w/factor;
  }


  /**
   * Returns a hpoint whose elements are the direction cosines
   * of the vector
   * @return hpoint representing direction cosines
   */
  public hpoint dircos() {
    normalize();
    float alpha = getx(); /* cos of angle between vector and x axis */
    float beta = gety(); /* cos of angle between vector and y axis */
    float gamma = getz(); /* cos of angle between vector and z axis */
    return new hpoint(alpha, beta, gamma, 1);
  }

  /**
   * String representation of the hpoint.
   * @return String rep of hpoint
   */
  public String toString() {
    String answer;
    
    answer = "x: " + Float.toString(getx()) + ",y: " +
      Float.toString(gety()) + ",z: " + Float.toString(getz());
    return answer;
  }

}

/**
 * Non-homogeneous point.
 */

class point {
  public float x, y, z;

  public point ( float a, float b, float c ) {
    x = a;
    y = b;
    z = c;
  }

  /* create a normal point from a homogenous point */
  public point (hpoint hp) {
    x = hp.getx();
    y = hp.gety();
    z = hp.getz();
  }
}
