Javaアプレットによるレイトレーシング。
// $Header: /home/abe/school/manual/ray-project/RCS/java.html,v 1.2 2010/06/05 16:29:47 abe Exp abe $
import java.awt.*;
import java.util.*;
import java.applet.*;
public class SimpleRaytracing extends Applet
{
public void init()
{
setLayout(new BorderLayout());
RayCanvas c = new RayCanvas();
add("Center", c);
//add("South", controls = new RayControls(c));
}
public void start()
{
}
public void stop()
{
}
public boolean handleEvent(Event e)
{
if (e.id == Event.WINDOW_DESTROY)
{
System.exit(0);
}
return false;
}
public static void main(String args[])
{
Frame f = new Frame("SimpleRaytracing");
SimpleRaytracing simpleRaytracing = new SimpleRaytracing();
simpleRaytracing.init();
simpleRaytracing.start();
f.add("Center", simpleRaytracing);
f.resize(200, 200);
f.show();
}
}
class RayCanvas extends Canvas
{
Vec light_data = new Vec(-0.57735, -0.57735, 0.57735);
Vec from = new Vec(0.0, 0.0, 7.0);
Vec point = new Vec(0.0, 0.0, 0.0); // center of a sphere
Vec ambient = new Vec(0.2, 0.2, 0.2);
int xsize = 200;
int ysize = 200;
public void paint(Graphics g)
{
for(int y = 0; y < ysize; y++)
{
for(int x = 0; x < xsize; x++)
{
Color col = scan(x, y);
g.setColor(col);
g.drawLine(x, y, x, y);
}
}
}
Color scan(int x, int y)
{
double b, c, d, det, t, t1, t2;
double tmin = 10000000.0;
double radius = 1.0;
Vec to = new Vec((double)x/(double)xsize - 0.5, (double)y/(double)ysize - 0.5, 4.0);
Vec vector = new Vec(point.x, point.y, point.z);
to.vminus(from);
to.vnormarize();
vector.vminus(from);
b = -to.innerproduct(vector);
c = vector.innerproduct(vector) - radius*radius;
d = b * b - c;
if(d < 0) // ray is not intersect
return new Color(0, 0, 0);
det = Math.sqrt(d);
t1 = -b + det;
t2 = -b - det;
if(t1 < 0) // object is behind eye
return new Color(0, 0, 0);
if(t2 > 0.0)
t = t2;
else
t = t1;
if(tmin > t)
tmin = t;
if(tmin >= 10000000.0)
return new Color(0, 0, 0);
return shading(tmin, from, to, point);
}
Color shading(double t, Vec from, Vec to, Vec point)
{
int i;
int r, g, b;
double val, rval, gval, bval;
Vec too = new Vec(to.x * t, to.y * t, to.z * t);
Vec c = new Vec(from.x, from.y, from.z);
Vec col = new Vec(1.0, 0.0, 0.0);
c.vplus(too);
c.vminus(point);
c.vnormarize();
val = c.innerproduct(light_data);
if(val < 0.0)
val = 0.0;
rval = col.x * val + ambient.x;
gval = col.y * val + ambient.y;
bval = col.z * val + ambient.z;
if(rval > 1.0)
rval = 1.0;
if(gval > 1.0)
gval = 1.0;
if(bval > 1.0)
bval = 1.0;
return new Color((int)(255.0 * rval), (int)(255.0 * gval), (int)(255.0 * bval));
}
public void redraw(boolean ok, double x, double y, double z)
{
this.point.x = x;
this.point.y = y;
this.point.z = z;
repaint();
}
}
// $Header: /home/abe/school/manual/ray-project/RCS/java.html,v 1.2 2010/06/05 16:29:47 abe Exp abe $
class Vec
{
double x, y, z;
public Vec(Vec a)
{
x = a.getX();
y = a.getY();
z = a.getZ();
}
public Vec(double xval, double yval, double zval)
{
x = xval;
y = yval;
z = zval;
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public double getZ()
{
return z;
}
public void vplus(Vec a)
{
this.x += a.x;
this.y += a.y;
this.z += a.z;
}
public void vminus(Vec a)
{
this.x -= a.x;
this.y -= a.y;
this.z -= a.z;
}
public double innerproduct(Vec a)
{
return a.x * this.x + a.y * this.y + a.z * this.z;
}
public void vnormarize()
{
double d;
d = Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z);
this.x /= d;
this.y /= d;
this.z /= d;
}
public void print()
{
System.out.println("x " + this.x + " y " + this.y + " z " + this.z);
}
public void test(Vec a)
{
Vec b = new Vec(a);
b.vplus(a);
b.print();
}
}
<HTML>
<HEAD>
<TITLE>
simple raytracing
</TITLE>
</HEAD>
<BODY>
<H1>
simple raytracing
</H1>
<APPLET CODE = "SimpleRaytracing.class" CODEBASE="." WIDTH = 300 HEIGHT = 300>
</APPLET>
</BODY>
</HTML>