Un programme de visualisation de segments de droite 3D rastérisées au moyen de l'algorithme de Bresenham généralisé en 3D : Bresenham3D.java
Pages WEB de référence au format Javadoc pour ces classes
/**
* La classe <code>Bresenham3D</code> implante un programme d'affichage
* de segments de droites 3D rasterises pour l'affichage au moyen
* de l'algorithme de Bresenham.
*
* @author Nicolas Janey
* @author nicolas.janey@univ-fcomte.fr
* @version 1.0, 16/11/08
*/
public class Bresenham3D {
private static int temporisation = 50;
public static void main(String [] args) {
ApplicationFrame f;
f = new ApplicationFrame("Tracé de segment 3D par algorithme de Bresenham");
f.add("Bresenham 3D",(Afficheur) new Afficheur3D());
f.setSize(480,360);
f.setLocation(50,250);
ThreadTacheDeFond ttdf = new ThreadTacheDeFond(temporisation,f.getCanvas());
f.setAnimator(ttdf);
ttdf.start();
f.setAnimated(false);
f.setVisible(true);
}
}
La classe implantant la visualisation : Afficheur3D.java
import java.awt.*;
/**
* La classe <code>Afficheur3D</code> implante l'interface
* {@link Afficheur Afficheur} pour developper une methode
* d'affichage par rasterisation d'un segment de droite 3D.
*
* @author Nicolas Janey
* @author nicolas.janey@univ-fcomte.fr
* @version 1.0, 12/11/08
*/
public class Afficheur3D implements Afficheur {
private int tx;
private int ty;
private int zoom = 15;
private Graphics g;
private Ortho ortho;
/**
* Methode d'affichage executee en boucle infinie pour realiser
* l'affichage d'un objet en projection parallele orthographique.
*
* @param g l'objet <code>Graphics</code> d'affichage.
* @param numeroImage le nombre de fois ou cette methode
* a deja ete appelee.
* @param tx la largeur (en pixels) de la zone de dessin.
* @param ty la hauteur (en pixels) de la zone de dessin.
*/
public void paint(Graphics g,int numeroImage,int tx,int ty) {
this.tx = tx;
this.ty = ty;
this.g = g;
g.drawString("3D en 26 connexité",10,20);
g.drawString("Image : "+numeroImage,10,40);
double angle = (numeroImage+40)*Math.PI/45.0;
double x = Math.round(1000.0*Math.sin(angle))/100.0;
double y = 4.0;
double z = Math.round(1000.0*Math.cos(angle))/100.0;
g.drawString("x : "+x,10,60);
g.drawString("y : "+y,10,80);
g.drawString("z : "+z,10,100);
ortho = new Ortho(new Position3D(x,y,z),new Position3D(0.0,0.0,0.0));
ligne(-9,-5,-3,10,6,2);
Position3D pi = transform(new Position3D(-8.5,-4.5,-2.5));
Position3D pf = transform(new Position3D(10.5,6.5,2.5));
g.setColor(Color.blue);
g.drawLine(xEcran(pi),yEcran(pi),
xEcran(pf),yEcran(pf));
}
private int xEcran(Position3D p) {
return((int) (tx/2+p.getX()*zoom));
}
private int yEcran(Position3D p) {
return((int) (ty/2-p.getY()*zoom));
}
private Position3D transform(Position3D p) {
return(ortho.transform(p));
}
private void traceVoxel(int x,int y,int z) {
double px = x;
double py = y;
double pz = z;
Position3D p000 = transform(new Position3D(px,py,pz));
Position3D p100 = transform(new Position3D(px+1,py,pz));
Position3D p010 = transform(new Position3D(px,py+1,pz));
Position3D p001 = transform(new Position3D(px,py,pz+1));
Position3D p110 = transform(new Position3D(px+1,py+1,pz));
Position3D p011 = transform(new Position3D(px,py+1,pz+1));
Position3D p101 = transform(new Position3D(px+1,py,pz+1));
Position3D p111 = transform(new Position3D(px+1,py+1,pz+1));
g.drawLine(xEcran(p000),yEcran(p000),xEcran(p100),yEcran(p100));
g.drawLine(xEcran(p000),yEcran(p000),xEcran(p010),yEcran(p010));
g.drawLine(xEcran(p000),yEcran(p000),xEcran(p001),yEcran(p001));
g.drawLine(xEcran(p110),yEcran(p110),xEcran(p100),yEcran(p100));
g.drawLine(xEcran(p101),yEcran(p101),xEcran(p100),yEcran(p100));
g.drawLine(xEcran(p011),yEcran(p011),xEcran(p010),yEcran(p010));
g.drawLine(xEcran(p110),yEcran(p110),xEcran(p010),yEcran(p010));
g.drawLine(xEcran(p101),yEcran(p101),xEcran(p001),yEcran(p001));
g.drawLine(xEcran(p011),yEcran(p011),xEcran(p001),yEcran(p001));
g.drawLine(xEcran(p110),yEcran(p110),xEcran(p111),yEcran(p111));
g.drawLine(xEcran(p011),yEcran(p011),xEcran(p111),yEcran(p111));
g.drawLine(xEcran(p101),yEcran(p101),xEcran(p111),yEcran(p111));
}
/* xf > xi */
/* yf > yi */
/* xf-xi > yf-yi */
private void ligne(int xi,int yi,int zi,
int xf,int yf,int zf) {
int dx,dy,dz;
int cumuly,cumulz;
int x,y,z ;
x = xi ;
y = yi ;
z = zi ;
dx = xf - xi ;
dy = yf - yi ;
dz = zf - zi ;
traceVoxel(x,y,z) ;
cumulz = cumuly = dx >> 1 ;
for ( x = xi+1 ; x <= xf ; x++ ) {
cumuly += dy ;
if (cumuly >= dx) {
cumuly -= dx ;
y += 1 ; }
cumulz += dz ;
if (cumulz >= dx) {
cumulz -= dx ;
z += 1 ; }
traceVoxel(x,y,z) ; }
}
}