/* Affichages de triangles. Illustration des procédures récursives et des boucles */ import java.awt.*; import javax.swing.JFrame; import javax.swing.JPanel; public class Triangles{ private static void drawTriangle (Graphics g, int x, int y, int largeur, int hauteur){ // trace un triangle isocèle inscrit dans un rectangle, la base // du triangle est celle du rectangle et le sommet est le centre // du haut du rectangle // détermine les trois sommets et on trace une ligne entre eux if (hauteur>=0 && largeur>=0){ int x1 = x+largeur/2, y1 = y, x2 = x, y2 = y+hauteur, x3 = x+largeur, y3 = y+hauteur; g.drawLine(x1,y1,x2,y2); g.drawLine(x2,y2,x3,y3); g.drawLine(x3,y3,x1,y1); } } private static void remplirTriangle (Graphics g, int x, int y, int largeur, int hauteur){ if (largeur>0 && hauteur>0){ drawTriangle(g,x,y,largeur,hauteur); remplirTriangle(g,x+1,y+1,largeur-2,hauteur-2); } else if (largeur>0) g.drawLine(x,y,x+largeur,y); else if (hauteur>0) g.drawLine(x,y,x,y+hauteur); } private static void fillTriangleRec(Graphics g, float x, int y, float largeur, int hauteur){ // remplit un triangle en traçant la base en se rappelant récursivement // pour tracer le triangle au-dessus de cette ligne. // attention x et largeur sont des float pour éviter les accumulations // d'erreur de troncatures ou d'arrondi... g.drawLine(Math.round(x),y+hauteur,Math.round(x+largeur),y+hauteur); if(hauteur>1){ int hauteur1 = hauteur-1; // nouvelle hauteur // largeur et décalage en x calculés par la loi des triangles semblables float largeur1 = largeur*hauteur1/hauteur; float dx = (largeur-largeur1)/2; fillTriangleRec(g,x+dx,y,largeur1,hauteur1); } } @SuppressWarnings("unused") private static void fillTriangle(Graphics g, int x, int y, int largeur, int hauteur){ // remplit un triangle de façon itérative // on recalcule à chaque ligne la valeur exacte du point de départ float ratio = (float)largeur/hauteur; for (int dy = 0; dy<= hauteur; dy++){ float largeur1 = dy*ratio; float dx = (largeur-largeur1)/2; g.drawLine(Math.round(x+dx),y+dy,Math.round(x+dx+largeur1),y+dy); } } private static float surface(int largeur,int hauteur){ return (largeur*hauteur)/2.0f; } private static void drawTriangleSurface(Graphics g, int x, int y, int largeur, int hauteur){ drawTriangle(g,x,y,largeur,hauteur); g.drawString(Float.toString(surface(largeur,hauteur)),x+largeur/2,y+hauteur/2); } private static void testRemplirTriangle(Graphics g, int x, int y, int largeur, int hauteur){ g.setColor(Color.BLUE); remplirTriangle(g,x,y,largeur,hauteur); g.setColor(Color.RED); drawTriangle(g,x,y,largeur,hauteur); } private static void testFillTriangle(Graphics g, int x, int y, int largeur, int hauteur){ g.setColor(Color.GREEN); fillTriangleRec(g,x,y,largeur,hauteur); g.setColor(Color.YELLOW); drawTriangle(g,x,y,largeur,hauteur); } static class Dessin extends JPanel{ public void paintComponent(Graphics g) { super.paintComponent(g); testRemplirTriangle(g,10,0,200,150); testFillTriangle(g,100,175,20,150); g.setColor(Color.BLACK); drawTriangleSurface(g,150,150,150,175); } } public static void main(String[] args){ JFrame f = new JFrame(); Dessin d = new Dessin(); f.getContentPane().add(d); f.setSize(400,400); f.setLocation(100,100); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }