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