/**
 * Punto geometrico, ha le due coordinate e un insieme di
 * funzioni di utilita'.
 */
public class Punto
{
  /** Coordinata x. */ public double x;
  /** Coordinata y. */ public double y;

  /** Construisce un punto date due coordinate. */  
  public Punto (double xx, double yy) { x = xx; y = yy; }
  
  /** Construisce un punto collocato nell'origine. */
  public Punto () { x = y = 0.0; }

  /* Funzioni di utilita' */
  
  /** Controlla se due punti hanno stesse coordinate. */
  public static boolean uguali(Punto p1, Punto p2)
  { return ((p1.x==p2.x) && (p1.y==p2.y)); }

  /** Somma due punti coordinata per coordinata. */
  public static Punto somma(Punto p1, Punto p2)
  { return new Punto(p1.x+p2.x, p1.y+p2.y); }
    
  /** Moltiplica per fattore m le due coordinate del punto. */
  public static Punto moltiplica(Punto p, double m)
  { return new Punto(p.x*m, p.y*m); }

  /** Normalizza questo punto, pensato come vettore. */
  public void normalizza()
  {
    double l = Math.sqrt(x*x + y*y);
    if (l!=0.0) {  x /= l; y /= l; }
  }
  
  /** Calcola la normale al segmento che unisce i due punti. */
  public static Punto normale(Punto p1, Punto p2)
  {
    Punto aux = new Punto (p1.y-p2.y, p2.x-p1.x);
    aux.normalizza();
    return aux;
  }

  /* Determinante  |a b|
                   |c d| */
  private static double determinante2(double a, double b,
                                      double c, double d)
  {  return ((a*d)-(b*c)); }

  /* Determinante  |a1 a2 a3|
                   |b1 b2 b3|
                   |c1 c2 c3| */                          
  private static double determinante3(double a1, double a2, double a3,
                               double b1, double b2, double b3,
                               double c1, double c2, double c3)
  {
    return ( a1*determinante2(b2,b3,c2,c3) -
             a2*determinante2(b1,b3,c1,c3) +
             a3*determinante2(b1,b2,c1,c2) );
  }
  
  /** Rappresenta la svolta a destra. */
  public final static int DESTRA = 1;
  /** Rappresenta la svolta a sinistra. */
  public final static int SINISTRA = -1;
  /** Rappresenta l'allineamento. */
  public final static int IN_LINEA = 0;
  
  /** Calcola che svolta definisce il punto p rispetto al
      segmento che va da p1 a p2: destra, sinistra o allineata. */
  public static int svolta(Punto p, Punto p1, Punto p2)
  {  
    double d = determinante2(p.x-p1.x, p.y-p1.y,
                             p2.x-p1.x, p2.y-p1.y);
    //System.out.println("det [" + (p.x-p1.x) + " " + ( p.y-p1.y) + "]");
    //System.out.println("    [" + (p2.x-p1.x) + " " + (p2.y-p1.y) + "]= " + d);
    if (d>0.0) return DESTRA;
    else if (d<0.0) return SINISTRA;
         else return IN_LINEA;
  }

}
