La classe CoordonneesHomogenes3D est la classe de base de notre hiérarchie.

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe coordonnees homogenes en trois dimensions */

public class CoordonneesHomogenes3D {
  protected double [] c;

  public CoordonneesHomogenes3D() {
    c = new double[4];
  }

  public CoordonneesHomogenes3D(double x,double y,double z,double t) {
    c = new double[4];
    c[0] = x;
    c[1] = y;
    c[2] = z;
    c[3] = t;
  }

  public CoordonneesHomogenes3D(CoordonneesHomogenes3D ch) {
    c = new double[4];
    c[0] = ch.c[0];
    c[1] = ch.c[1];
    c[2] = ch.c[2];
    c[3] = ch.c[3];
  }

  public CoordonneesHomogenes3D(double [] t) {
    c = new double[4];
    c[0] = t[0];
    c[1] = t[1];
    c[2] = t[2];
    c[3] = t[3];
  }
  
  public void setX(double x) {
    c[0] = x;
  }
  
  public double getX() {
    return(c[0]);
  }
  
  public void setY(double y) {
    c[1] = y;
  }
  
  public double getY() {
    return(c[1]);
  }
  
  public void setZ(double z) {
    c[2] = z;
  }
  
  public double getZ() {
    return(c[2]);
  }
  
  public void setT(double t) {
    c[3] = t;
  }
  
  public double getT() {
    return(c[3]);
  }
    
  public double [] getValue() {
    double [] nc = new double[4];
    nc[0] = c[0];
    nc[1] = c[1];
    nc[2] = c[2];
    nc[3] = c[3];
    return(nc);
  }
  
  public String toString() {
    String s = "[";
    int i;
    for ( i = 0 ; i < c.length-1 ; i++ )
      s += (c[i]+",");
    s += c[i]+"]";
    return(s);
  }
}

CoordonneesHomogenes3D.java

La classe Position3D est dérivée de la classe CoordonneesHomogenes3D pour représenter des positions dans un espace 3D (4ème coordonnée initialisée à 1.0F).

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe position en coordonnees homogenes         */

public class Position3D extends CoordonneesHomogenes3D {

  public Position3D() {
    super(0.0,0.0,0.0,1.0);
  }

  public Position3D(double x,double y,double z) {
    super(x,y,z,1.0);
  }

  public Position3D(Position3D p) {
    super(p);
  }
}

Position3D.java

La classe Direction3D est dérivée de la classe CoordonneesHomogenes3D pour représenter des directions dans un espace 3D (4ème coordonnée initialisée à 0.0F).

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe direction en coordonnees homogenes        */

public class Direction3D extends CoordonneesHomogenes3D {

  public Direction3D() {
    super(0.0,0.0,1.0,0.0);
  }

  public Direction3D(double x,double y,double z) {
    super(x,y,z,0.0);
  }

  public Direction3D(Direction3D p) {
    super(p);
  }

  public Direction3D(Position3D pi,
                     Position3D pf) throws ArithmeticException {
    double dx = pf.c[0]-pi.c[0];
    double dy = pf.c[1]-pi.c[1];
    double dz = pf.c[2]-pi.c[2];
    double d = Math.sqrt(dx*dx+dy*dy+dz*dz);
    if ( d == 0.0 ) {
      throw new ArithmeticException(); }
    c = new double[4];
    c[0] = dx/d;
    c[1] = dy/d;
    c[2] = dz/d;
    c[3] = 0.0;
  }
}

Direction3D.java

La classe TransformationGeometrique3D la classe de base de représentation de transformations géométriques quelconques en coordonnées homogènes dans un espace 3D.
Le constructeur sans paramètre crée une transformation géométrique identité.
Trois méthodes sont développées pour:

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe transformation geometrique 3D             */
/* en coordonnees homogenes                             */

public class TransformationGeometrique3D {
  protected double [][] c;

  public TransformationGeometrique3D() {
    c = new double[4][4];
    for ( int i = 0 ; i < 4 ; i++ )
      c[i][i] = 1.0;
  }
  
  public TransformationGeometrique3D(double [][] t) {
    c = new double[4][4];
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 4 ; j++ )
        c[i][j] = t[i][j];
  }
  
  public TransformationGeometrique3D(TransformationGeometrique3D t) {
    c = new double[4][4];
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 4 ; j++ )
        c[i][j] = t.c[i][j];
  }
  
  public Position3D transform(Position3D p) {
    double [] v = multiplication(p.getValue());
    return(new Position3D(v[0],v[1],v[2]));
  }
  
  public Direction3D transform(Direction3D d) {
    double [] v = multiplication(d.getValue());
    return(new Direction3D(v[0],v[1],v[2]));
  }  
  
  private double [] multiplication(double [] v) {
    double [] r = new double[4];
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 4 ; j++ )
        r[i] += c[i][j]*v[j];
    return(r);
  }
  
  public TransformationGeometrique3D compose(TransformationGeometrique3D m) {
    TransformationGeometrique3D r = new TransformationGeometrique3D();
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 4 ; j++ ) {
        r.c[i][j] = 0.0;
        for ( int k = 0 ; k < 4 ; k++ )
          r.c[i][j] += c[i][k]*m.c[k][j]; }
    return(r);
  }
  
  public static TransformationGeometrique3D compose(TransformationGeometrique3D m1,
                                                    TransformationGeometrique3D m2) {
    return(m1.compose(m2));
  }
  
  public String toString() {
    String s = "[";
    for ( int j = 0 ; j < c.length ; j++ ) {
      if ( j > 0 )
        s += " ";
      s += "[";
      for ( int i = 0 ; i < c[j].length ; i++ ) {
        s += c[j][i];
        if ( i < c[j].length-1 )
          s += ","; }
      s += "]";
      if ( j < c.length-1 )
        s += "\n"; }
    s += "]";
    return(s);
  }
}

TransformationGeometrique3D.java

La classe Identite3D est dérivée de la classe TransformationGeometrique3D.

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe transformation geometrique identite       */

public class Identite3D extends TransformationGeometrique3D {

  public Identite3D() {
    super();
  }
}

Identite3D.java

La classe Translation3D est dérivée de la classe TransformationGeometrique3D.

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe transformation geometrique translation    */

public class Translation3D extends TransformationGeometrique3D {

  public Translation3D() {
    super();
  }

  public Translation3D(double x,double y,double z) {
    super();
    c[0][3] = x;
    c[1][3] = y;
    c[2][3] = z;
  }

  public Translation3D(Direction3D d) {
    super();
    c[0][3] = d.getX();
    c[1][3] = d.getY();
    c[2][3] = d.getZ();
  }

  public Translation3D(Translation3D t) {
    super(t);
  }
}

Translation3D.java

La classe Rotation3D est dérivée de la classe TransformationGeometrique3D.
Elle comporte un constructeur pour la création d'une rotation autour d'un axe défini par une direction arbitraire passant par l'origine.

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe transformation geometrique rotation       */

public class Rotation3D extends TransformationGeometrique3D {

  public Rotation3D() {
    super();
  }

  public Rotation3D(double a,
                    double dx,double dy,double dz) throws ArithmeticException {
    super();
    remplissage(a,dx,dy,dz);
  }

  public Rotation3D(double a,
                    Direction3D d) throws ArithmeticException {
    super();
    remplissage(a,d.getX(),d.getY(),d.getZ());
  }

  public Rotation3D(Rotation3D rt) {
    super(rt);
  }

  private void remplissage(double a,
                           double x,double y,double z) throws ArithmeticException {
    a = a/180.0*(double) Math.PI;
    double c = Math.cos(a);
    double s = Math.sin(a);
    double d = Math.sqrt(x*x+y*y+z*z);
    if ( d == 0 ) {
      throw new ArithmeticException(); }
    x /= d;
    y /= d;
    z /= d;
    double x2 = x*x;
    double y2 = y*y;
    double z2 = z*z;
    double xs = x*s;
    double ys = y*s;
    double zs = z*s;
    double mc = 1.0 - c;
    double xymc = x*y*mc;
    double xzmc = x*z*mc;
    double yzmc = y*z*mc;
    this.c[0][0] = x2+c*(1.0-x2);
    this.c[0][1] = xymc-zs;
    this.c[0][2] = xzmc+ys;
    this.c[1][0] = xymc+zs;
    this.c[1][1] = y2+c*(1.0-y2);
    this.c[1][2] = yzmc-xs;
    this.c[2][0] = xzmc-ys;
    this.c[2][1] = yzmc+xs;
    this.c[2][2] = z2+c*(1.0-z2);
  }
}

Rotation3D.java

La classe Scale3D est dérivée de la classe TransformationGeometrique3D.

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Une classe transformation geometrique scale          */

public class Scale3D extends TransformationGeometrique3D {

  public Scale3D() {
    super();
  }

  public Scale3D(double rx,double ry,double rz) {
    super();
    c[0][0] = rx;
    c[1][1] = ry;
    c[2][2] = rz;
  }

  public Scale3D(Scale3D sc) {
    super(sc);
  }
}

Scale3D.java

Pages WEB de référence au format Javadoc pour ces hiérarchies de classes

La classe MathematiquesMatricielles est utilisée pour tester nos hiérarchies.

/* Auteur: Nicolas JANEY                                */
/* nicolas.janey@univ-fcomte.fr                         */
/* Octobre 2008                                         */
/* Un programme de test de l'utilisation                */
/* des coordonnees homogenes et des transformations     */
/* geometriques en coordonnees homogenes                */

public class MathematiquesMatricielles {
  
  public static void main(String [] args) {
    Position3D p1 = new Position3D(-1.1, 0.1, 1.0);
    Position3D p2 = new Position3D( 0.3,-1.6, 3.0);
    Position3D p3 = new Position3D( 1.2,-0.2,-1.0);
    Position3D p4 = new Position3D(-2.2, 0.9, 2.2);
    Direction3D d1 = new Direction3D(-1.1, 0.1, 1.0);
    Direction3D d2 = new Direction3D( 0.3,-1.6, 3.0);
    Direction3D d3 = new Direction3D( 1.2,-0.2,-1.0);
    Direction3D d4 = new Direction3D(-2.2, 0.9, 2.2);

    Rotation3D r = new Rotation3D(25.0,1.0,0.5,1.0);
    Translation3D t = new Translation3D(1.5,2.0,0.6);
    Scale3D s = new Scale3D(3.0,1.5,0.5);
    
    Position3D np1 = t.transform(p1);
    Position3D np2 = r.transform(p2);
    Position3D np3 = s.transform(p3);
    Direction3D nd1 = t.transform(d1);
    Direction3D nd2 = r.transform(d2);
    Direction3D nd3 = s.transform(d3);

    System.out.println("Translation");
    System.out.println(p1);
    System.out.println(np1);
    System.out.println(d1);
    System.out.println(nd1);
    System.out.println();
    System.out.println("Rotation");
    System.out.println(p2);
    System.out.println(np2);
    System.out.println(d2);
    System.out.println(nd2);
    System.out.println();
    System.out.println("Scale");
    System.out.println(p3);
    System.out.println(np3);
    System.out.println(d3);
    System.out.println(nd3);
    
    TransformationGeometrique3D tg;
    tg = TransformationGeometrique3D.compose(r,t);
    tg = TransformationGeometrique3D.compose(s,tg);
    Position3D np4 = tg.transform(p4);
    Position3D nnp4 = t.transform(p4);
    nnp4 = r.transform(nnp4);
    nnp4 = s.transform(nnp4);
    Direction3D nd4 = tg.transform(d4);
    Direction3D nnd4 = t.transform(d4);
    nnd4 = r.transform(nnd4);
    nnd4 = s.transform(nnd4);

    System.out.println();
    System.out.println("Composition");
    System.out.println();
    System.out.println(tg);
    System.out.println();
    System.out.println(p4);
    System.out.println(np4);
    System.out.println(nnp4);
    System.out.println(d4);
    System.out.println(nd4);
    System.out.println(nnd4);
    System.out.println();
  }
}

MathematiquesMatricielles.java

Son exécution conduit à l'affichage suivant (noter les erreurs de calcul liées à la non précision infinie des processeurs).

Translation
[-1.1,0.1,1.0,1.0]
[0.3999999999999999,2.1,1.6,1.0]
[-1.1,0.1,1.0,0.0]
[-1.1,0.1,1.0,0.0]

Rotation
[0.3,-1.6,3.0,1.0]
[1.2494058692232737,-2.1587541009678155,2.329971181260634,1.0]
[0.3,-1.6,3.0,0.0]
[1.2494058692232737,-2.1587541009678155,2.329971181260634,0.0]

Scale
[1.2,-0.2,-1.0,1.0]
[3.5999999999999996,-0.30000000000000004,-0.5,1.0]
[1.2,-0.2,-1.0,0.0]
[3.5999999999999996,-0.30000000000000004,-0.5,0.0]

Composition

[[2.84384631172775,-0.7827750481724987,0.5475412123584995,3.0287440986617273]
[0.45384899939514944,1.3750770493821998,-0.3913875240862493,3.1960950834053743]
[-0.049615885187149884,0.15128299979838314,0.4739743852879583,0.5125268029888164]
[0.0,0.0,0.0,1.0]]

[-2.2,0.9,2.2,1.0]
[-2.727624663305873,2.5741440761902767,1.8005800978525992,1.0]
[-2.727624663305873,2.574144076190277,1.8005800978525994,1.0]
[-2.2,0.9,2.2,0.0]
[-5.7563687619676,-0.6219510072150976,1.2880532948637828,0.0]
[-5.7563687619676,-0.6219510072150976,1.2880532948637828,0.0]

RETOUR