Опубликован: 27.09.2006 | Уровень: для всех | Доступ: платный | ВУЗ: Московский государственный индустриальный университет
Лекция 13:
Изображение полиэдра
SmartDrawer.java
/** * @author Е.А. Роганов * @version 1.1 * Класс SmartDrawer, обеспечивающий изображение проекции полиэдра * с использованием двумерного хеширования граней. */ public class SmartDrawer extends ShadowDrawer { /** * Количество гнезд сетки в строке и столбце. */ private final static int SIZE = 50; /** * Максимальное число граней в гнезде. */ private final static int MAXFACETS = 200; /** * Массив гнезд, в которые попадает обрабатываемое ребро. */ private boolean[][] sockets; /** * Массив количеств граней в гнездах. */ private int[][] nmbFacets; /** * Массив множеств номеров граней. */ private int[][][] hashFacets; /** * Найти последний индекс гнезда, соответствующий t. * @param t Координата. */ private int lastVal(double t) { return Math.min((int)(t*SIZE),SIZE-1); } /** * Найти первый индекс гнезда, соответствующий t. * @param t Координата. */ private int firstVal(double t) { return (int)(t*SIZE); } /** * Конструктор класса. * @param p Полиэдр. * @param pr Вектор проектирования. * @param angle Угол поворота в плоскости проекции. */ public SmartDrawer(Polyedr p, R3Vector pr, double angle) { super(p, pr, angle); nmbFacets = new int[SIZE][SIZE]; hashFacets = new int[SIZE][SIZE][MAXFACETS]; int i,j,k; int imax = p.getFacetsQuantity(); for (i=0; i<imax; i++) { Facet f=p.getFacet(i); k = f.getVertexesQuantity(); double x0 = 1., y0 = 1., x1 = 0., y1 = 0.; for (j=0; j<k; j++) { R3Vector v = f.getVertex(j); double x = xnProection(v); double y = ynProection(v); if (x < x0) x0 = x; if (y < y0) y0 = y; if (x > x1) x1 = x; if (y > y1) y1 = y; } int jm = lastVal(x1); int km = lastVal(y1); for (j=firstVal(x0); j<=jm; j++) for (k=firstVal(y0); k<=km; k++) hashFacets[ j ][ k ][ nmbFacets[j][k]++ ] = i; } } /** * Учесть тень от всех граней. */ protected void addShadow() { int i,j,k; double x0 = Math.min(xnProection(begin), xnProection(end)); double x1 = Math.max(xnProection(begin), xnProection(end)); double y0 = Math.min(ynProection(begin), ynProection(end)); double y1 = Math.max(ynProection(begin), ynProection(end)); int jm = lastVal(x1); int km = lastVal(y1); for (j=firstVal(x0); j<=jm; j++) for (k=firstVal(y0); k<=km; k++) for (i=0; i<nmbFacets[j][k]; i++) addShadow(p.getFacet( hashFacets[j][k][i] )); } }
PolyedrTest.java
import java.util.*; import java.io.*; /** * @author Е.А. Роганов * @version 1.1 * Класс PolyedrTest, ... */ public class PolyedrTest { /** * Функция main. * @param args Массив аргументов командной строки. * @exception Exception Исключительная ситуация, возникающая * при ошибках чтения или преобразования данных из файла. */ public static void main(String[] args) throws Exception { Polyedr p = new Polyedr(args[0]); int type = Xterm.inputInt("Возможные типы изображения полиэдра:\n"+ " без удаления невидимых линий - 0\n"+ " с удалением невидимых ребер - 1\n"+ " с использованием хеширования - 2\n"+ "Выберите тип изображения (от 0 до 2) -> " ); while (true) { R3Vector pr = new R3Vector(); double angle = Xterm.inputDouble("Угол поворота в плоскости " + "проекции (в градусах): "); switch (type) { case 0: SimpleDrawer d = new SimpleDrawer(p, pr, Math.PI*angle/180.0); d.draw(); break; case 1: ShadowDrawer sd = new ShadowDrawer(p, pr, Math.PI*angle/180.0); sd.draw(); break; case 2: SmartDrawer smd = new SmartDrawer(p, pr, Math.PI*angle/180.0); smd.draw(); break; default: Xterm.println("Неверный тип изображения"); } Thread.currentThread().setPriority(Thread.MIN_PRIORITY); } } }