package graphics.raytracer;
import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
public class DoImage {
private Targets scene = Targets.getTargets();
private Dimension d = null;
private int pixels[][] = null;
public Dimension getSize() {
return d;
}
public void setSize(Dimension _d) {
d = _d;
pixels = new int[d.width][d.height];
}
public DoImage(Dimension _d) {
d = _d;
pixels = new int[d.width][d.height];
}
public void doTheWork() {
int screenWidth = d.width;
int screenHeight = d.height;
int pixY = 0;
int pixX = 0;
double deltaY = 1.0 / screenHeight;
double deltaX = 1.0 / screenWidth;
double tmpy = 1.0;
double tmpz = 0.0;
int screenStartLine = 0;
int screenEndLine = 2 * screenHeight;
for (pixY = screenStartLine; pixY < screenEndLine; pixY++) {
double tmpx = -1.0;
tmpy -= deltaY;
pixX = renderALine(screenWidth, deltaX, tmpx, tmpy, tmpz, pixY);
}
}
public void setBand(Dimension _band) {
band = _band;
}
private Dimension band = new Dimension(0, 200);
private int renderALine(int w,
double xstep,
double tmpx,
double tmpy,
double tmpz,
int pixY) {
int pixX;
int xMin = 0;
int xMax = 2 * w;
for (pixX = xMin; pixX < xMax; pixX++) {
tmpx += xstep;
int realX = pixX / 2;
int realY = pixY / 2;
if (realX < band.width) continue;
if (realX > band.height) continue;
int c = computePixel(tmpx, tmpy, tmpz);
addPixel(c, realX, w, realY);
}
return pixX;
}
private int computePixel(double tmpx, double tmpy, double tmpz) {
Vec projP = new Vec(tmpx, tmpy, tmpz);
int c = paintPix(projP);
return c;
}
private void addPixel(int c, int realX, int w, int realY) {
getPixels()[realX][realY] = (255 << 24) | (c << 16) | (c << 8) | (c << 0);
}
public static Image int2Image(int i[][]) {
Toolkit tk = Toolkit.getDefaultToolkit();
int width = i.length;
int height = i[0].length;
int pels[] = new int[width * height];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
pels[x + y * width] = i[x][y];
return tk.createImage(
new MemoryImageSource(width, height,
ColorModel.getRGBdefault(),
pels, 0, width));
}
public Image int2SubImage(int i[][]) {
int startx = band.width;
int endx = band.height;
int xWidth = endx - startx;
int sx = 0;
int subImage[][] = new int[xWidth][d.height];
for (int x = 0; x < subImage.length; x++)
for (int y = 0; y < subImage[0].length; y++)
subImage[x][y] = i[x + band.width][y];
return int2Image(subImage);
}
public int[][] int2SubInt(int i[][]) {
int startx = band.width;
int endx = band.height;
int xWidth = endx - startx;
int sx = 0;
int subImage[][] = new int[xWidth][d.height];
for (int x = 0; x < subImage.length; x++)
for (int y = 0; y < subImage[0].length; y++)
subImage[x][y] = i[x + band.width][y];
return subImage;
}
public int[][] getSubPixels() {
doTheWork();
return int2SubInt(pixels);
}
public Image getImage() {
doTheWork();
return int2SubImage(pixels);
}
public Image getSubBand() {
doTheWork();
Toolkit tk = Toolkit.getDefaultToolkit();
int xSubImageWidth = band.height - band.width;
int ySubImageHeight = d.height;
int subImage[] = new int[xSubImageWidth * ySubImageHeight];
int i = 0;
for (int y = 0; y < d.height; y++)
for (int x = band.height; x < band.width; x++)
System.out.println("dimension=" + band);
return tk.createImage(
new MemoryImageSource(xSubImageWidth, xSubImageWidth,
ColorModel.getRGBdefault(),
subImage, band.height, band.width));
}
private int paintPix(Vec projP) {
double t[] = new double[1];
int color = 0;
Vec R1 = new Vec(projP);
R1.sub(scene.VRP);
R1.normalize();
t[0] = 0.0;
int obj = intersectObjects(scene.VRP, R1, t, 0, false);
if (t[0] > 0.0) {
color = ((Target) scene.getElementAt(obj)).shade(obj,
R1, t);
}
color += 16;
if (color > 255)
color = 255;
return color;
}
private int intersectObjects(Vec R0, Vec R1, double result[], int object,
boolean shadowCheck) {
double minDist = 0.0, dist;
int hit = -1;
for (int i = 0; i < scene.getSize(); i++) {
if ((shadowCheck == true) && (object == i))
continue;
dist = ((Target) scene.getElementAt(i)).intersectTest(R0,
R1, i);
if (dist == 0.0)
continue;
if ((minDist == 0.0) && (dist > 0.0)) {
minDist = dist;
hit = i;
} else if ((dist > 0.0) && (dist < minDist)) {
minDist = dist;
hit = i;
}
}
result[0] = minDist;
return hit;
}
public int[][] getPixels() {
return pixels;
}
}