/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2007                                         */

public class Position {
  public float x;
  public float y;
  public float z;

  public Position() {
    x = y = z = 0.0F;
  }

  public Position(float x,float y,float z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }

  public Position(Position p) {
    x = p.x;
    y = p.y;
    z = p.z;
  }

  public float distance(Position p) {
    float dx = p.x - x;
    float dy = p.y - y;
    float dz = p.z - z;
    return((float) Math.sqrt(dx*dx + dy*dy + dz*dz));
  }

  public float carreDistance(Position p) {
    float dx = p.x - x;
    float dy = p.y - y;
    float dz = p.z - z;
    return(dx*dx + dy*dy + dz*dz);
  }
  
  public String toString() {
    return("["+x+","+y+","+z+"]");
  }
}

Position.java

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2007                                         */

public class Direction {
  public float dx;
  public float dy;
  public float dz;

  public Direction() {
    dx = dy = 0.0F;
    dz = -1.0F;
  }

  public Direction(float dx,float dy,float dz) {
    this.dx = dx;
    this.dy = dy;
    this.dz = dz;
  }

  public Direction(Direction d) {
    dx = d.dx;
    dy = d.dy;
    dz = d.dz;
  }

  public Direction(Position p1,Position p2) {
    dx = p2.x-p1.x;
    dy = p2.y-p1.y;
    dz = p2.z-p1.z;
    normalise();
  }

  public Direction(Position p1,Position p2,boolean normalisation) {
    dx = p2.x-p1.x;
    dy = p2.y-p1.y;
    dz = p2.z-p1.z;
    if ( normalisation )
      normalise();
  }

  public float norme() {
    return((float) Math.sqrt(dx*dx + dy*dy + dz*dz));
  }

  public void normalise() {
    float norme = norme();
    if ( norme != 0 ) {
      dx /= norme;
      dy /= norme;
      dz /= norme; }
  }

  public float produitScalaire(Direction d) {
    return(dx*d.dx + dy*d.dy + dz*d.dz);
  }

  public static float produitScalaire(Direction d1,Direction d2) {
    return(d1.dx*d2.dx + d1.dy*d2.dy + d1.dz*d2.dz);
  }

  public Direction produitVectoriel(Direction d) {
    return(new Direction(dy*d.dz - dz*d.dy,
                         dz*d.dx - dx*d.dz,
                         dx*d.dy - dy*d.dx));
  }

  public static Direction produitVectoriel(Direction d1,Direction d2) {
    return(new Direction(d1.dy*d2.dz - d1.dz*d2.dy,
                         d1.dz*d2.dx - d1.dx*d2.dz,
                         d1.dx*d2.dy - d1.dy*d2.dx));
  }

  public boolean testVecteurNul() {
    return((dx == 0.0F) && (dy == 0.0F) && (dz == 0.0F));
  }

  public boolean testCodirection(Direction d) {
    float ps = produitScalaire(d);
    if ( ps < 0.0F )
      return(false);
    return(ps == norme()*d.norme());
  }
  
  public String toString() {
    return("["+dx+","+dy+","+dz+"]");
  }
}

Direction.java

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2007                                         */

public class Facette4 {
  public Position p1;
  public Position p2;
  public Position p3;
  public Position p4;

  public Facette4() {
    p1 = new Position();
    p2 = new Position();
    p3 = new Position();
    p4 = new Position();
  }

  public Facette4(Position p1,Position p2,Position p3,Position p4) {
    this.p1 = new Position(p1);
    this.p2 = new Position(p2);
    this.p3 = new Position(p3);
    this.p4 = new Position(p4);
  }

  public Facette4(Facette4 f) {
    p1 = new Position(f.p1);
    p2 = new Position(f.p2);
    p3 = new Position(f.p3);
    p4 = new Position(f.p4);
  }

  public boolean testPlanarite() {
    Direction d12 = new Direction(p1,p2,false);
    Direction d13 = new Direction(p1,p3,false);
    Direction normale = d12.produitVectoriel(d13);
    Direction d14 = new Direction(p1,p4,false);
    return(d14.produitScalaire(normale) == 0.0F);
  }

  public boolean testConvexite() {
    Direction d12 = new Direction(p1,p2,false);
    Direction d14 = new Direction(p1,p4,false);
    Direction n1 = d12.produitVectoriel(d14);
    Direction d23 = new Direction(p2,p3,false);
    Direction d21 = new Direction(p2,p1,false);
    Direction n2 = d23.produitVectoriel(d21);
    if ( !n1.testCodirection(n2) )
      return(false);
    Direction d34 = new Direction(p3,p4,false);
    Direction d32 = new Direction(p3,p2,false);
    Direction n3 = d34.produitVectoriel(d32);
    if ( !n1.testCodirection(n3) )
      return(false);
    Direction d41 = new Direction(p4,p1,false);
    Direction d43 = new Direction(p4,p3,false);
    Direction n4 = d41.produitVectoriel(d43);
    if ( !n1.testCodirection(n4) )
      return(false);
    return(true);
  }
  
  public String toString() {
    return("["+p1+",\n "+p2+",\n "+p3+",\n "+p4+"]");
  }
}

Facette4.java

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2007                                         */

public class RayonLumineux {
  public Position o;
  public Direction d;

  public RayonLumineux() {
    o = new Position();
    d = new Direction();
  }
  
  public RayonLumineux(Position o,Direction d) {
    this.o = new Position(o);
    this.d = new Direction(d);
  }
  
  public RayonLumineux(RayonLumineux r) {
    o = new Position(r.o);
    d = new Direction(r.d);
  }
  
  public boolean existeIntersection(Sphere s) {
    return(s.existeIntersection(this));
  }
  
  public Position premiereIntersection(Sphere s) {
    return(s.premiereIntersection(this));
  }
  
  public String toString() {
    return("["+o+",\n"+d+"]");
  }
}

RayonLumineux.java

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2007                                         */

public class Sphere {
  public Position c;
  public float r;

  public Sphere() {
    c = new Position();
    r = 1.0F;
  }
  
  public Sphere(Position c,float r) {
    this.c = new Position(c);
    this.r = r;
  }
  
  public Sphere(Sphere s) {
    c = new Position(s.c);
    r = s.r;
  }
  
  public boolean existeIntersection(RayonLumineux rl) {
    float sx = rl.o.x - c.x;
    float sy = rl.o.y - c.y;
    float sz = rl.o.z - c.z;
    float a = rl.d.dx*rl.d.dx + rl.d.dy*rl.d.dy + rl.d.dz*rl.d.dz;
    float b = 2.0F*(rl.d.dx*sx + rl.d.dy*sy + rl.d.dz*sz);
    float c = sx*sx + sy*sy +sz*sz - r*r;
    float delta = b*b-4*a*c;
    if ( delta < 0.0F )
      return(false);
    if ( delta == 0 ) {
      float t = -b/2.0F/a;
      return( t >= 0.0F); } 
    float t1 = (-b-((float) Math.sqrt(delta)))/2.0F/a;
    if ( t1 >= 0 )
      return(true);
    float t2 = (-b+((float) Math.sqrt(delta)))/2.0F/a;
    return( t2 >= 0 );
  }

  private Position positionSurRayon(RayonLumineux rl,float t) {
    return(new Position(rl.d.dx*t+rl.o.x,
                        rl.d.dy*t+rl.o.y,
                        rl.d.dz*t+rl.o.z));
  }
  
  public Position premiereIntersection(RayonLumineux rl) {
    float sx = rl.o.x - c.x;
    float sy = rl.o.y - c.y;
    float sz = rl.o.z - c.z;
    float a = rl.d.dx*rl.d.dx + rl.d.dy*rl.d.dy + rl.d.dz*rl.d.dz;
    float b = 2.0F*(rl.d.dx*sx + rl.d.dy*sy + rl.d.dz*sz);
    float c = sx*sx + sy*sy +sz*sz - r*r;
    float delta = b*b-4*a*c;
    if ( delta < 0.0F )
      return(null);
    if ( delta == 0 ) {
      float t = -b/2.0F/a;
      if ( t >= 0.0F)
        return(positionSurRayon(rl,t));
        else
        return(null); }
    { float t = (-b-((float) Math.sqrt(delta)))/2.0F/a;
      if ( t >= 0 )
        return(positionSurRayon(rl,t)); }
    { float t = (-b+((float) Math.sqrt(delta)))/2.0F/a;
      if ( t >= 0 )
        return(positionSurRayon(rl,t)); }
    return(null);
  }
  
  public String toString() {
    return("["+c+","+r+"]");
  }
}

Sphere.java

RETOUR