/* Alunos: * Cleber Mira ra:980866 * Andre Veras ra:980645 * */ package pckInterface; import java.awt.Graphics; import java.awt.Color; import java.awt.Rectangle; import java.awt.Point; import Gravura; import Ponto; import Retangulo; import Escala; public final class GravuraImpl extends Gravura { // CONSTRUTOR private Graphics g; private Escala e; private double ppmm; public GravuraImpl(Graphics g, Escala e, double ppmm) { this.g = g; this.e = e; this.ppmm = ppmm; } // PARAMETROS PERSISTENTES private int rPena = 0; // Raio nominal da pena (pixels). private Color cPena; // Cor da pena (null para não traçar contornos). private Color cPincel; // Cor do pincel (null para não preencher figs). private Rectangle rTela = new Rectangle(); private Point pTela = new Point(); private Point qTela = new Point(); private Point uTela = new Point(); private Point vTela = new Point(); public final void mudaLimites(Retangulo r) { e.mapaParaTela(r, rTela); g.setClip(rTela.x, rTela.y, rTela.width, rTela.height); } public final void restringeLimites(Retangulo r) { e.mapaParaTela(r, rTela); g.clipRect(rTela.x, rTela.y, rTela.width, rTela.height); } public final void mudaRaioDaPena(int raio) { this.rPena = raio; } public final void mudaCorDoPincel(Color cor) { this.cPincel = cor; } public final void mudaCorDaPena(Color cor) { this.cPena = cor; } private static Color corXOR = new Color(128,128,128); public final void modoXOR() { g.setXORMode(corXOR); } public final void modoSET() { g.setPaintMode(); } public final void translada(int dx, int dy) { g.translate(dx,dy); } public final double tamanhoDoPixel() { return e.unidadesPorPixel(); } public final double pixelsPorMilimetro() { return ppmm; } // FIGURAS GEOMÉTRICAS ELEMENTARES // In order to understand the mapping between pixels and // user units, it is advisable to ignore the Sun explanations // about the semantics of Graphics, and re-interpret the // latter as follows: // // - the pixels are centered at integer coordinates. // - lines are stroked with a diamond brush of radius 0.5; // any pixel whose center is touched by the brush gets // painted. // - in figure filling, pixels whose centers are inside the // figure get painted. // - ties are broken by assuming that all client coordinates // are implicitly displaced by (-eps,-eps). public final void ponto(Ponto p) { e.mapaParaTela(p, pTela); if (cPena != null) { g.setColor(cPena); g.fillOval(pTela.x - rPena, pTela.y - rPena, 2*rPena+1, 2*rPena+1); } } public final void linha(int p1_x,int p1_y,int p2_x,int p2_y) { Ponto p = new Ponto((double)p1_x,(double)p1_y); Ponto q = new Ponto((double)p2_x,(double)p2_y); linha(p,q); } public final void linha(Ponto p, Ponto q) // Um segmento de reta, engordado por "raio" (em pixels!) // em todas as direcoes. { if (cPena != null) { e.mapaParaTela(p, pTela); e.mapaParaTela(q, qTela); g.setColor(cPena); if (rPena == 0) { g.drawLine(pTela.x, pTela.y, qTela.x, qTela.y); } else { linhaGrossa(pTela.x, pTela.y, qTela.x, qTela.y); } } } private int[] xTela = new int[6]; private int[] yTela = new int[6]; public final void poligono(Ponto[] p) // Um polígono preenchido ou não. { int np = p.length; if (np > xTela.length) { xTela = new int[np + 6]; yTela = new int[np + 6]; } for (int i = 0; i < np; i++) { e.mapaParaTela(p[i], pTela); xTela[i] = pTela.x; yTela[i] = pTela.y; } if (cPincel != null) { g.setColor(cPincel); g.fillPolygon(xTela, yTela, np); } if (cPena != null) { g.setColor(cPena); if (rPena == 0) { g.drawPolygon(xTela, yTela, np); } else { int j = np - 1; for (int i = 0; i < np; i++) { linhaGrossa(xTela[j], yTela[j], xTela[i], yTela[i]); j = i; } } } } public final void retangulo(Retangulo r) // Um retângulo, preenchido ou não. { e.mapaParaTela(r, rTela); if (cPincel != null) { g.setColor(cPincel); g.fillRect(rTela.x, rTela.y, rTela.width, rTela.height); } if (cPena != null) { g.setColor(cPena); for (int d = -rPena; d <= rPena; d++) { g.drawRect(rTela.x+d, rTela.y+d, rTela.width-2*d, rTela.height-2*d); } } } private void linhaGrossa(int xP, int yP, int xQ, int yQ) // Desenha uma linha de raio rPena de (xP,yP) a (xQ,yQ). { // Solução porca e lenta - desenha múltiplas linhas. // Cuidado - altera temporariamente "g" int dMax = (int) rPena; int r2 = (int)(rPena*rPena); for (int dx = -dMax; dx <= dMax; dx++) { for (int dy = -dMax; dy <= dMax; dy++) { if (dx*dx + dy*dy <= r2) { g.translate(+dx, +dy); g.drawLine(xP, yP, xQ, yQ); g.translate(-dx, -dy); } } } } }