Опубликован: 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(".");
}
}