Опубликован: 27.09.2006 | Уровень: для всех | Доступ: платный | ВУЗ: Московский государственный индустриальный университет
Лекция 13:
Изображение полиэдра
AwtDrawer.java
import java.awt.*; /** * @author Е.А. Роганов * @version 1.1 * Класс AwtDrawer, обеспечивающий визуализацию * плоского изображения. */ public class AwtDrawer extends Frame { /** * Ширина области рисования. */ private static final int XLEN = 500; /** * Высота области рисования. */ private static final int YLEN = 500; /** * Ширина "полей" вокруг области рисования. */ private static final int DELTA= 100; /** * Внеэкранный буфер. */ private Image offScrImage; /** * Графический контекст внеэкранного буфера. */ private Graphics offScrGC; /** * Графический контекст фрейма на экране. */ private Graphics g; /** * Конструктор класса. */ public AwtDrawer() { super("Построение изображения полиэдра"); setSize(XLEN+2*DELTA, YLEN+2*DELTA); setBackground(Color.white); g = getGraphics(); show(); offScrImage = createImage(XLEN+2*DELTA, YLEN+2*DELTA); offScrGC = offScrImage.getGraphics(); offScrGC.setColor(Color.white); offScrGC.fillRect(0,0,XLEN+2*DELTA, YLEN+2*DELTA); offScrGC.setColor(Color.black); } /** * Изобразить отрезок на плоскости, заданный его концами. * @param xb X-координата начала отрезка ( 0 <= xb <= 1 ). * @param yb Y-координата начала отрезка ( 0 <= yb <= 1 ). * @param xe X-координата конца отрезка ( 0 <= xe <= 1 ). * @param ye Y-координата конца отрезка ( 0 <= ye <= 1 ). */ public final void draw(double xb, double yb, double xe, double ye) { int x0 = DELTA + (int)(XLEN * xb); int y0 = DELTA + (int)(YLEN * yb); int x1 = DELTA + (int)(XLEN * xe); int y1 = DELTA + (int)(YLEN * ye); offScrGC.drawLine(x0, y0, x1, y1); } /** * Переизобразить содержимое фрейма. */ public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(offScrImage, 0, 0, this); } }
SimpleDrawer.java
/** * @author Е.А. Роганов * @version 1.1 * Класс SimpleDrawer, обеспечивающий изображение проекции полиэдра. */ public class SimpleDrawer extends AwtDrawer { /** * Полиэдр. */ protected Polyedr p; /** * Единичный вектор проектирования. */ protected R3Vector pr; /** * Единичный X-вектор плоскости проектирования. */ private R3Vector x; /** * Единичный Y-вектор плоскости проектирования. */ private R3Vector y; /** * Минимальная X-координата проекции полиэдра. */ private double xmin; /** * Минимальная Y-координата проекции полиэдра. */ private double ymin; /** * Размер проекции полиэдра. */ private double size; /** * Вычислить X-координату проекции точки. * @param v Трехмерный вектор. * @return X-координата проекции этого вектора. */ private double xProection(R3Vector v) { return R3Vector.scalMul(v, x); } /** * Вычислить Y-координату проекции точки. * @param v Трехмерный вектор. * @return Y-координата проекции этого вектора. */ private double yProection(R3Vector v) { return R3Vector.scalMul(v, y); } /** * Вычислить нормализованную X-координату проекции точки. * @param v Трехмерный вектор. * @return Нормализованная X-координата проекции этого вектора. */ protected double xnProection(R3Vector v) { return (xProection(v) - xmin)/size; } /** * Вычислить нормализованную Y-координату проекции точки. * @param v Трехмерный вектор. * @return Нормализованная Y-координата проекции этого вектора. */ protected double ynProection(R3Vector v) { return (yProection(v) - ymin)/size; } /** * Конструктор класса. * @param p Полиэдр. * @param pr Вектор проектирования. * @param angle Угол поворота в плоскости проекции. */ public SimpleDrawer(Polyedr p, R3Vector pr, double angle) { this.p = p; this.pr = pr.normalize(); double a = pr.getX(); double b = pr.getY(); double c = pr.getZ(); if (a != 0. || b != 0.) { x = new R3Vector(-b, a, 0.); } else { x = new R3Vector(0., c, -b); } y = R3Vector.vectMul(x, pr); x.normalize(); y.normalize(); R3Vector nx = R3Vector.plus( R3Vector.mul(Math.cos(angle), x), R3Vector.mul(-Math.sin(angle), y) ); R3Vector ny = R3Vector.plus( R3Vector.mul(Math.sin(angle), x), R3Vector.mul(Math.cos(angle), y) ); x = nx; y = ny; xmin = ymin = Double.MAX_VALUE; double xmax, ymax; xmax = ymax = Double.MIN_VALUE; for (int i=0; i<p.getVertexesQuantity(); i++) { double xi = xProection(p.getVertex(i)); double yi = yProection(p.getVertex(i)); if (xi < xmin) xmin = xi; if (yi < ymin) ymin = yi; if (xi > xmax) xmax = xi; if (yi > ymax) ymax = yi; } size = ymax - ymin; if (xmax - xmin < size) size = xmax - xmin; } /** * Изобразить проекцию полиэдра. */ public final void draw() { for (int i=0; i<p.getEdgesQuantity(); i++) drawEdge(p.getEdge(i)); Xterm.print("\n"); } /** * Изобразить ребро полиэдра. * @param s Обрабатываемое ребро полиэдра. */ public void drawEdge(Edge s) { Vertex begin = s.getBegin(); Vertex end = s.getEnd(); draw(xnProection(begin), ynProection(begin), xnProection(end), ynProection(end)); Xterm.print("."); } }