diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..fceb480 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..760dd8d --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + RayTracer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/Image.png b/Image.png new file mode 100644 index 0000000..ef41f0e Binary files /dev/null and b/Image.png differ diff --git a/ShadowImage1.png b/ShadowImage1.png new file mode 100644 index 0000000..91ff26d Binary files /dev/null and b/ShadowImage1.png differ diff --git a/ShadowImage10.png b/ShadowImage10.png new file mode 100644 index 0000000..f48c0f5 Binary files /dev/null and b/ShadowImage10.png differ diff --git a/ShadowImage11.png b/ShadowImage11.png new file mode 100644 index 0000000..34106fc Binary files /dev/null and b/ShadowImage11.png differ diff --git a/ShadowImage12.png b/ShadowImage12.png new file mode 100644 index 0000000..39f4fed Binary files /dev/null and b/ShadowImage12.png differ diff --git a/ShadowImage13.png b/ShadowImage13.png new file mode 100644 index 0000000..3bf6414 Binary files /dev/null and b/ShadowImage13.png differ diff --git a/ShadowImage14.png b/ShadowImage14.png new file mode 100644 index 0000000..53ff3dc Binary files /dev/null and b/ShadowImage14.png differ diff --git a/ShadowImage15.png b/ShadowImage15.png new file mode 100644 index 0000000..a71755c Binary files /dev/null and b/ShadowImage15.png differ diff --git a/ShadowImage16.png b/ShadowImage16.png new file mode 100644 index 0000000..3254e37 Binary files /dev/null and b/ShadowImage16.png differ diff --git a/ShadowImage17.png b/ShadowImage17.png new file mode 100644 index 0000000..62b47b2 Binary files /dev/null and b/ShadowImage17.png differ diff --git a/ShadowImage18.png b/ShadowImage18.png new file mode 100644 index 0000000..81ec715 Binary files /dev/null and b/ShadowImage18.png differ diff --git a/ShadowImage19.png b/ShadowImage19.png new file mode 100644 index 0000000..778f5d0 Binary files /dev/null and b/ShadowImage19.png differ diff --git a/ShadowImage2.png b/ShadowImage2.png new file mode 100644 index 0000000..6285b34 Binary files /dev/null and b/ShadowImage2.png differ diff --git a/ShadowImage20.png b/ShadowImage20.png new file mode 100644 index 0000000..74016ec Binary files /dev/null and b/ShadowImage20.png differ diff --git a/ShadowImage21.png b/ShadowImage21.png new file mode 100644 index 0000000..0befa96 Binary files /dev/null and b/ShadowImage21.png differ diff --git a/ShadowImage22.png b/ShadowImage22.png new file mode 100644 index 0000000..11b2aa1 Binary files /dev/null and b/ShadowImage22.png differ diff --git a/ShadowImage23.png b/ShadowImage23.png new file mode 100644 index 0000000..036d912 Binary files /dev/null and b/ShadowImage23.png differ diff --git a/ShadowImage24.png b/ShadowImage24.png new file mode 100644 index 0000000..6f3a5c1 Binary files /dev/null and b/ShadowImage24.png differ diff --git a/ShadowImage25.png b/ShadowImage25.png new file mode 100644 index 0000000..29e2001 Binary files /dev/null and b/ShadowImage25.png differ diff --git a/ShadowImage26.png b/ShadowImage26.png new file mode 100644 index 0000000..8dd8179 Binary files /dev/null and b/ShadowImage26.png differ diff --git a/ShadowImage27.png b/ShadowImage27.png new file mode 100644 index 0000000..7920c99 Binary files /dev/null and b/ShadowImage27.png differ diff --git a/ShadowImage3.png b/ShadowImage3.png new file mode 100644 index 0000000..66e01b0 Binary files /dev/null and b/ShadowImage3.png differ diff --git a/ShadowImage4.png b/ShadowImage4.png new file mode 100644 index 0000000..5e203a1 Binary files /dev/null and b/ShadowImage4.png differ diff --git a/ShadowImage5.png b/ShadowImage5.png new file mode 100644 index 0000000..524d5a3 Binary files /dev/null and b/ShadowImage5.png differ diff --git a/ShadowImage6.png b/ShadowImage6.png new file mode 100644 index 0000000..876eb00 Binary files /dev/null and b/ShadowImage6.png differ diff --git a/ShadowImage7.png b/ShadowImage7.png new file mode 100644 index 0000000..5ad22af Binary files /dev/null and b/ShadowImage7.png differ diff --git a/ShadowImage8.png b/ShadowImage8.png new file mode 100644 index 0000000..e33802e Binary files /dev/null and b/ShadowImage8.png differ diff --git a/ShadowImage9.png b/ShadowImage9.png new file mode 100644 index 0000000..70c5a89 Binary files /dev/null and b/ShadowImage9.png differ diff --git a/bin/geometry/GeometricObject.class b/bin/geometry/GeometricObject.class new file mode 100644 index 0000000..a14f433 Binary files /dev/null and b/bin/geometry/GeometricObject.class differ diff --git a/bin/geometry/Plane.class b/bin/geometry/Plane.class new file mode 100644 index 0000000..b5b5159 Binary files /dev/null and b/bin/geometry/Plane.class differ diff --git a/bin/geometry/Sphere.class b/bin/geometry/Sphere.class new file mode 100644 index 0000000..aaa9527 Binary files /dev/null and b/bin/geometry/Sphere.class differ diff --git a/bin/main/Driver.class b/bin/main/Driver.class new file mode 100644 index 0000000..77ad8e8 Binary files /dev/null and b/bin/main/Driver.class differ diff --git a/bin/main/Tracer.class b/bin/main/Tracer.class new file mode 100644 index 0000000..cacd129 Binary files /dev/null and b/bin/main/Tracer.class differ diff --git a/bin/projection/Orthographic.class b/bin/projection/Orthographic.class new file mode 100644 index 0000000..af274cd Binary files /dev/null and b/bin/projection/Orthographic.class differ diff --git a/bin/projection/Perspective.class b/bin/projection/Perspective.class new file mode 100644 index 0000000..b67ed30 Binary files /dev/null and b/bin/projection/Perspective.class differ diff --git a/bin/projection/Projection.class b/bin/projection/Projection.class new file mode 100644 index 0000000..f506f06 Binary files /dev/null and b/bin/projection/Projection.class differ diff --git a/bin/sampling/JitteredSample.class b/bin/sampling/JitteredSample.class new file mode 100644 index 0000000..0946fb0 Binary files /dev/null and b/bin/sampling/JitteredSample.class differ diff --git a/bin/sampling/RegularSample.class b/bin/sampling/RegularSample.class new file mode 100644 index 0000000..95ebc00 Binary files /dev/null and b/bin/sampling/RegularSample.class differ diff --git a/bin/sampling/Sampler.class b/bin/sampling/Sampler.class new file mode 100644 index 0000000..efb97d1 Binary files /dev/null and b/bin/sampling/Sampler.class differ diff --git a/bin/scene/Light.class b/bin/scene/Light.class new file mode 100644 index 0000000..698a253 Binary files /dev/null and b/bin/scene/Light.class differ diff --git a/bin/scene/ViewPlane.class b/bin/scene/ViewPlane.class new file mode 100644 index 0000000..8b7138e Binary files /dev/null and b/bin/scene/ViewPlane.class differ diff --git a/bin/scene/World.class b/bin/scene/World.class new file mode 100644 index 0000000..50860cf Binary files /dev/null and b/bin/scene/World.class differ diff --git a/bin/utility/Color.class b/bin/utility/Color.class new file mode 100644 index 0000000..6f6ca94 Binary files /dev/null and b/bin/utility/Color.class differ diff --git a/bin/utility/Image.class b/bin/utility/Image.class new file mode 100644 index 0000000..f132914 Binary files /dev/null and b/bin/utility/Image.class differ diff --git a/bin/utility/LightingCoeff.class b/bin/utility/LightingCoeff.class new file mode 100644 index 0000000..8242473 Binary files /dev/null and b/bin/utility/LightingCoeff.class differ diff --git a/bin/utility/Point2D.class b/bin/utility/Point2D.class new file mode 100644 index 0000000..8ccc7c5 Binary files /dev/null and b/bin/utility/Point2D.class differ diff --git a/bin/utility/Point3D.class b/bin/utility/Point3D.class new file mode 100644 index 0000000..40a85c5 Binary files /dev/null and b/bin/utility/Point3D.class differ diff --git a/bin/utility/Ray.class b/bin/utility/Ray.class new file mode 100644 index 0000000..7d7c6fc Binary files /dev/null and b/bin/utility/Ray.class differ diff --git a/bin/utility/Vector3D.class b/bin/utility/Vector3D.class new file mode 100644 index 0000000..13f4d58 Binary files /dev/null and b/bin/utility/Vector3D.class differ diff --git a/src/geometry/GeometricObject.java b/src/geometry/GeometricObject.java new file mode 100644 index 0000000..0467ead --- /dev/null +++ b/src/geometry/GeometricObject.java @@ -0,0 +1,62 @@ +package geometry; + +import main.Driver; +import scene.Light; +import utility.Color; +import utility.LightingCoeff; +import utility.Point3D; +import utility.Ray; +import utility.Vector3D; + +public abstract class GeometricObject { + + public LightingCoeff k_d; + public LightingCoeff k_s; + public LightingCoeff amb; + + public abstract double hit(Ray ray); + + public abstract Vector3D getNormal(Point3D point); + + public GeometricObject(LightingCoeff k_d, LightingCoeff k_s, LightingCoeff amb) { + this.k_d = k_d; + this.k_s = k_s; + this.amb = amb; + } + + public Color getColorNoLight() { + return new Color(amb.r, amb.g, amb.b); + } + public Color getColor(Point3D point, Light light) { + Vector3D n = getNormal(point); + + // Initialize with ambiance + double new_r = amb.r; + double new_g = amb.g; + double new_b = amb.b; + + Vector3D l = light.location.sub_vec(point); + l.normalize(); + n.normalize(); + + // Perform Diffuse Reflection + double diffuse = Math.max(0.0, n.dot(l)); + new_r += k_d.r * light.I * diffuse; + new_g += k_d.g * light.I * diffuse; + new_b += k_d.b * light.I * diffuse; + + // Perform Spectral Reflection + Vector3D v = Driver.eye.sub_vec(point); + v.normalize(); + Vector3D h = v.add(l); + h.normalize(); + + double spectral = Math.max(0.0, Math.pow(n.dot(h), 3)); + new_r += k_s.r * light.I * spectral; + new_g += k_s.g * light.I * spectral; + new_b += k_s.b * light.I * spectral; + + return new Color(new_r, new_g, new_b); + } + +} diff --git a/src/geometry/Plane.java b/src/geometry/Plane.java new file mode 100644 index 0000000..55be00c --- /dev/null +++ b/src/geometry/Plane.java @@ -0,0 +1,44 @@ +package geometry; + +import utility.Color; +import utility.LightingCoeff; +import utility.Point3D; +import utility.Ray; +import utility.Vector3D; + +public class Plane extends GeometricObject { + Point3D point; + Vector3D normal; + + /* + * Given a point on the plane as well as the normal The locus of the plane + * is the set of all points such that (p - o) dot n = 0 + */ + + public Plane(Point3D point, Vector3D normal, LightingCoeff k_d, LightingCoeff k_s, LightingCoeff amb) { + super(k_d, k_s, amb); + this.point = new Point3D(point); + normal.normalize(); + this.normal = new Vector3D(normal); + } + + @Override + public double hit(Ray ray) { + /* + * (o + td - a) * n = 0 o*n + t(d*n) - a*n = 0 t(d*n) + (o-a)*n = 0 + * t(d*n) = (a-o)*n t = (a-o)*n/d*n + */ + double t = point.sub(ray.origin).dot(normal) / (ray.direction.dot(normal)); + + if (t > 10E-10) + return t; + else + return 0.0; + } + + @Override + public Vector3D getNormal(Point3D point) { + return normal; + } + +} diff --git a/src/geometry/Sphere.java b/src/geometry/Sphere.java new file mode 100644 index 0000000..3f5f9c8 --- /dev/null +++ b/src/geometry/Sphere.java @@ -0,0 +1,55 @@ +package geometry; + +import utility.Color; +import utility.LightingCoeff; +import utility.Point3D; +import utility.Ray; +import utility.Vector3D; + +public class Sphere extends GeometricObject { + + public Point3D center; + public double radius; + + public Sphere(Point3D center, double radius, LightingCoeff k_d, LightingCoeff k_s, LightingCoeff amb) { + super(k_d, k_s, amb); + this.center = new Point3D(center); + this.radius = radius; + } + + @Override + public double hit(Ray ray) { + /* + * (p-c)*(p-c) = r^2 (o+td-c)*(o+td-c) -r^2= 0 (td+o-c)(td+o-c) - r^2 = + * 0 (d*d)t + 2((o-c)*d)t + (o-c)*(o-c)-r^2 = 0 + */ + + Point3D o = ray.origin; + Vector3D d = ray.direction; + d.normalize(); + + double a = d.dot(d); + double b = 2 * ((o.sub(center)).dot(d)); + double c = (o.sub(center)).dot(o.sub(center)) - radius * radius; + + double disc = b * b - 4 * a * c; + if (disc < 0) { + return 0.0; // did not hit + } + + double t = ((-b) - Math.sqrt(disc)) / (2 * a); + if (t > 10E-9) + return t; + else + return 0.0; // No intersection + + } + + @Override + public Vector3D getNormal(Point3D point) { + Vector3D n = point.sub_vec(center); + n.normalize(); + return n; + } + +} diff --git a/src/main/Driver.java b/src/main/Driver.java new file mode 100644 index 0000000..b3696f1 --- /dev/null +++ b/src/main/Driver.java @@ -0,0 +1,47 @@ +package main; + +import projection.Perspective; +import projection.Projection; +import sampling.JitteredSample; +import sampling.RegularSample; +import sampling.Sampler; +import scene.World; +import utility.Image; +import utility.Point3D; + +/** + * @author yingliu + * + */ +public class Driver { + public static World world; + public static Image image; + public static Tracer tracer; + public static Sampler sampler; + public static Projection projection; + public static Point3D eye; + + public static void main(String[] args) { + for (int i = 1; i <= 27; i++) { + long start_time = System.nanoTime(); + world = new World(500, 500, 1.0, i); + image = new Image("ShadowImage" + Integer.toString(i) + ".png"); + tracer = new Tracer(); + sampler = new JitteredSample(2); + eye = new Point3D(-200.0, 200.0, 600.0); + projection = new Perspective(eye, new Point3D(), 45.0); + + int height = world.viewplane.height; + int width = world.viewplane.width; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + tracer.trace(x, y, true); + } + } + image.write("PNG"); + long end_time = System.nanoTime(); + System.out.println((end_time - start_time) / 1E9F); + } + } +} diff --git a/src/main/Tracer.java b/src/main/Tracer.java new file mode 100644 index 0000000..f41d8d0 --- /dev/null +++ b/src/main/Tracer.java @@ -0,0 +1,71 @@ +package main; + +import geometry.GeometricObject; +import scene.Light; +import utility.Color; +import utility.Point2D; +import utility.Point3D; +import utility.Ray; + +public class Tracer { + + public void trace(int x, int y, boolean shadow) { + int width = Driver.world.viewplane.width; + int height = Driver.world.viewplane.height; + int samples = Driver.sampler.samples; + + Color color = new Color(); + + for (int row = 0; row < samples; row++) { + for (int col = 0; col < samples; col++) { + Point2D point = Driver.sampler.sample(row, col, x, y); + Ray ray = Driver.projection.createRay(point); + ray.direction.normalize(); + double min_T = Double.MAX_VALUE; + boolean firstHit = false; + Color tempColor = new Color(Driver.world.background); + for (GeometricObject gObject : Driver.world.objects) { + double t = gObject.hit(ray); + if (t != 0.0) { + firstHit = true; + if (t < min_T) { + min_T = t; + Point3D hitPoint = ray.hitPoint(t); + // shading effects + boolean intersect = false; + for (Light light : Driver.world.lights) { + Ray ray_shad = new Ray(hitPoint, light.location); + if (shadow) { + for (GeometricObject gObject2 : Driver.world.objects) { + if (gObject2 != gObject) { + if (gObject2.hit(ray_shad) != 0.0) { + intersect = true; + break; + } + } + } + if (!intersect) + tempColor = gObject.getColor(hitPoint, light); + else { + tempColor = gObject.getColorNoLight(); + } + } else { + tempColor = gObject.getColor(hitPoint, light); + } + } + + } + } + } + + if (firstHit) + color.add(tempColor); + else { + color.add(Driver.world.background); + } + } + } + color.divide(samples * samples); + Driver.image.buffer.setRGB(width - x - 1, height - y - 1, color.toInteger()); + } +} diff --git a/src/projection/Orthographic.java b/src/projection/Orthographic.java new file mode 100644 index 0000000..0a38279 --- /dev/null +++ b/src/projection/Orthographic.java @@ -0,0 +1,16 @@ +package projection; + +import main.Driver; +import utility.Point2D; +import utility.Point3D; +import utility.Ray; +import utility.Vector3D; + +public class Orthographic extends Projection { + + @Override + public Ray createRay(Point2D point) { + double pixelSize = Driver.world.viewplane.size; + return new Ray(new Point3D(pixelSize * point.x, pixelSize * point.y, 100.0), new Vector3D(0.0, 0.0, -1.0)); + } +} diff --git a/src/projection/Perspective.java b/src/projection/Perspective.java new file mode 100644 index 0000000..16e398c --- /dev/null +++ b/src/projection/Perspective.java @@ -0,0 +1,27 @@ +package projection; + +import main.Driver; +import utility.Point2D; +import utility.Point3D; +import utility.Ray; + +public class Perspective extends Projection{ + + public Perspective(Point3D eye, Point3D lookat, double FOV) { + this.eye = new Point3D(eye); + this.lookat = new Point3D(lookat); + this.distance = Driver.world.viewplane.height/2/Math.tan(Math.toRadians(FOV)); + + compute_uvw(); + } + + @Override + public Ray createRay(Point2D point) { + Ray ray = new Ray(new Point3D(eye), u.mult(point.x).add(v.mult(point.y).sub(w.mult(distance)))); + ray.direction.normalize(); + + return ray; + + } + +} diff --git a/src/projection/Projection.java b/src/projection/Projection.java new file mode 100644 index 0000000..7622361 --- /dev/null +++ b/src/projection/Projection.java @@ -0,0 +1,31 @@ +package projection; + +import utility.Point2D; +import utility.Point3D; +import utility.Ray; +import utility.Vector3D; + +public abstract class Projection { + + public Point3D eye; + // Shoot out to the look at + public Point3D lookat; + public double distance; + public Vector3D u, v, w; + + public abstract Ray createRay(Point2D point); + + public void compute_uvw() { + w = eye.sub_vec(lookat); + w.normalize(); + + Vector3D up = new Vector3D(0.00424, 1.0, 0.00764); + + u = up.cross(w); + up.normalize(); + + v = w.cross(u); + v.normalize(); + } + +} diff --git a/src/sampling/JitteredSample.java b/src/sampling/JitteredSample.java new file mode 100644 index 0000000..e266845 --- /dev/null +++ b/src/sampling/JitteredSample.java @@ -0,0 +1,23 @@ +package sampling; + +import java.util.Random; + +import main.Driver; +import utility.Point2D; + +public class JitteredSample extends Sampler { + Random random = new Random(); + + public JitteredSample(int samples) { + this.samples = samples; + } + + @Override + public Point2D sample(int row, int col, int x, int y) { + Point2D point = new Point2D(); + point.x = x - Driver.world.viewplane.width / 2 + (col + random.nextFloat()) / samples; + point.y = y - Driver.world.viewplane.height / 2 + (row + random.nextFloat()) / samples; + return point; + } + +} diff --git a/src/sampling/RegularSample.java b/src/sampling/RegularSample.java new file mode 100644 index 0000000..2ac9bae --- /dev/null +++ b/src/sampling/RegularSample.java @@ -0,0 +1,21 @@ +package sampling; + +import main.Driver; +import utility.Point2D; + +public class RegularSample extends Sampler{ + + public RegularSample(int samples) { + this.samples = samples; + } + + @Override + public Point2D sample(int row, int col, int x, int y) { + Point2D point = new Point2D(); + point.x = x-Driver.world.viewplane.width/2+(col+0.5)/samples; + point.y = y-Driver.world.viewplane.height/2+(row+0.5)/samples; + return point; + } + + +} diff --git a/src/sampling/Sampler.java b/src/sampling/Sampler.java new file mode 100644 index 0000000..2932e69 --- /dev/null +++ b/src/sampling/Sampler.java @@ -0,0 +1,9 @@ +package sampling; + +import utility.Point2D; + +public abstract class Sampler { + public int samples; + + public abstract Point2D sample(int row, int col, int x, int y); +} diff --git a/src/scene/Light.java b/src/scene/Light.java new file mode 100644 index 0000000..8bcdf22 --- /dev/null +++ b/src/scene/Light.java @@ -0,0 +1,14 @@ +package scene; + +import utility.Point3D; + +public class Light { + public Point3D location; + public double I; //intensity + + public Light(Point3D location, double I) { + this.location = location; + this.I = I; + } + +} diff --git a/src/scene/ViewPlane.java b/src/scene/ViewPlane.java new file mode 100644 index 0000000..d6a4ac9 --- /dev/null +++ b/src/scene/ViewPlane.java @@ -0,0 +1,16 @@ +package scene; + +public class ViewPlane { + + public double size; + public int height; + public int width; + + //Represents our Screen + public ViewPlane(int width, int height, double size) { + this.width = width; + this.height = height; + this.size = size; + } + +} diff --git a/src/scene/World.java b/src/scene/World.java new file mode 100644 index 0000000..71323ec --- /dev/null +++ b/src/scene/World.java @@ -0,0 +1,54 @@ +package scene; + +import java.util.ArrayList; +import java.util.Random; + +import geometry.GeometricObject; +import geometry.Plane; +import geometry.Sphere; +import utility.Color; +import utility.LightingCoeff; +import utility.Point3D; +import utility.Vector3D; + +public class World { + + public ViewPlane viewplane; + public ArrayList objects; + public ArrayList lights; + public Color background; + + public World(int width, int height, double size, int sphereLimit) { + viewplane = new ViewPlane(width, height, size); + background = new Color(1.0F, 1.0F, 1.0F); + objects = new ArrayList(); + lights = new ArrayList(); + + /*objects.add(new Plane(new Point3D(-0.0,-200.0,-0.0), + new Vector3D(0.1,3,0.1), + new LightingCoeff("DIFF"), + new LightingCoeff("SPEC"), + new LightingCoeff("AMB") + ));*/ + + int numSphere = 0; + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + if(numSphere == sphereLimit) break; + numSphere++; + + Point3D center = new Point3D(100 * x, 100 * y, 100 * z); + + LightingCoeff k_d = new LightingCoeff("DIFF"); + LightingCoeff k_s = new LightingCoeff("SPEC"); + LightingCoeff k_a = new LightingCoeff("AMB"); + objects.add(new Sphere(center, 50.0, k_d, k_s, k_a)); + } + } + } + + lights.add(new Light(new Point3D(200.0, 200.0, 300.0), 0.7)); + + } +} diff --git a/src/utility/Color.java b/src/utility/Color.java new file mode 100644 index 0000000..0d442e5 --- /dev/null +++ b/src/utility/Color.java @@ -0,0 +1,53 @@ +package utility; + +public class Color { + public double r, g, b; + + public Color() { + r = 0.0; + g = 0.0; + b = 0.0; + } + + public Color(double r, double g, double b) { + this.r = r; + this.g = g; + this.b = b; + limit(); + } + + public void limit() { + r = Math.min(1.0, r); + g = Math.min(g, 1.0); + b = Math.min(b, 1.0); + + } + + public Color(Color c) { + r = c.r; + g = c.g; + b = c.b; + limit(); + } + + public void add(Color color) { + r = r + color.r; + g += color.g; + b += color.b; + } + + public void divide(int scalar) { + r /= scalar; + g /= scalar; + b /= scalar; + limit(); + } + + public int toInteger() { + return ((int) (r * 255) << 16) | ((int) (g * 255) << 8) | ((int) (b * 255)); + } + + public String toString() { + return "(" + r + "," + g + "." + b + ")"; + } +} diff --git a/src/utility/Image.java b/src/utility/Image.java new file mode 100644 index 0000000..7b1f660 --- /dev/null +++ b/src/utility/Image.java @@ -0,0 +1,32 @@ +package utility; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import main.Driver; + +public class Image { + + public BufferedImage buffer; + public File image; + + public Image(String filename) { + image = new File(filename); + int width = Driver.world.viewplane.width; + int height = Driver.world.viewplane.height; + buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + } + + public void write(String filetype) { + try { + ImageIO.write(buffer, filetype, image); + } catch (IOException e) { + System.err.println("Could not write image"); + System.exit(1); + } + } + +} diff --git a/src/utility/LightingCoeff.java b/src/utility/LightingCoeff.java new file mode 100644 index 0000000..4ac5cb1 --- /dev/null +++ b/src/utility/LightingCoeff.java @@ -0,0 +1,37 @@ +package utility; + +import java.util.Random; + +public class LightingCoeff { + public double r; + public double g; + public double b; + + public LightingCoeff(String type) { + Random rand = new Random(); + switch(type) { + case "AMB": + r = .5; + g = .5; + b = .5; + break; + case "SPEC": + r = .5; + g = .5; + b = .5; + break; + case "DIFF": + r = rand.nextDouble(); + g = rand.nextDouble(); + b = rand.nextDouble(); + break; + } + } + + public LightingCoeff(double r, double g, double b) { + this.r = r; + this.g = g; + this.b = b; + } + +} diff --git a/src/utility/Point2D.java b/src/utility/Point2D.java new file mode 100644 index 0000000..13a3e9b --- /dev/null +++ b/src/utility/Point2D.java @@ -0,0 +1,20 @@ +package utility; + +public class Point2D { + public double x, y; + + public Point2D() { + x = 0.0; + y = 0.0; + } + + public Point2D(double x, double y) { + this.x = x; + this.y = y; + } + + public Point2D(Point2D p) { + this.x = p.x; + this.y = p.y; + } +} diff --git a/src/utility/Point3D.java b/src/utility/Point3D.java new file mode 100644 index 0000000..fdb3d86 --- /dev/null +++ b/src/utility/Point3D.java @@ -0,0 +1,44 @@ +package utility; + +public class Point3D { + public double x, y, z; + + public Point3D() { + x = 0.0; + y = 0.0; + z = 0.0; + } + + public Point3D(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Point3D(Point3D point) { + x = point.x; + y = point.y; + z = point.z; + } + + public Point3D add(Point3D point) { + return new Point3D(x + point.x, y + point.y, z + point.z); + } + + public Point3D sub(Point3D point) { + return new Point3D(x - point.x, y - point.y, z - point.z); + } + + public Vector3D sub_vec(Point3D point) { + return new Vector3D(x - point.x, y - point.y, z - point.z); + } + + public double dot(Point3D point) { + return x * point.x + y * point.y + z * point.z; + } + + public double dot(Vector3D vector) { + return x * vector.x + y * vector.y + z * vector.z; + } + +} diff --git a/src/utility/Ray.java b/src/utility/Ray.java new file mode 100644 index 0000000..54ba0d3 --- /dev/null +++ b/src/utility/Ray.java @@ -0,0 +1,24 @@ +package utility; + +public class Ray { + public Point3D origin; + public Vector3D direction; + + public Ray(Point3D origin, Vector3D direction) { + this.origin = origin; + direction.normalize(); + this.direction = direction; + } + + public Ray(Point3D origin, Point3D end) { + this.origin = origin; + this.direction = end.sub_vec(origin); + this.direction.normalize(); + } + + public Point3D hitPoint(double t) { + Point3D p = new Point3D(origin.x + direction.x * t, origin.y + direction.y * t, origin.z + direction.z * t); + return p; + } + +} diff --git a/src/utility/Vector3D.java b/src/utility/Vector3D.java new file mode 100644 index 0000000..b2c898d --- /dev/null +++ b/src/utility/Vector3D.java @@ -0,0 +1,61 @@ +package utility; + +public class Vector3D { + public double x, y, z; + + public Vector3D() { + x = 0.0; + y = 0.0; + z = 0.0; + ; + } + + public Vector3D(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3D(Vector3D other) { + x = other.x; + y = other.y; + z = other.z; + } + + public Vector3D add(Vector3D vector) { + return new Vector3D(x + vector.x, y + vector.y, z + vector.z); + } + + public Vector3D sub(Vector3D vector) { + return new Vector3D(x - vector.x, y - vector.y, z - vector.z); + } + + public double dot(Vector3D v) { + return x * v.x + y * v.y + z * v.z; + } + + public double dot(Point3D point) { + return x * point.x + y * point.y + z * point.z; + } + + public double mag2() { + return x * x + y * y + z * z; + } + + public Vector3D mult(double scalar) { + return new Vector3D(x*scalar, y*scalar, z*scalar); + } + + public void normalize() { + double mag = Math.sqrt(mag2()); + + x /= mag; + y /= mag; + z /= mag; + + } + + public Vector3D cross(Vector3D v) { + return new Vector3D((y * v.z - z * v.y), -(x * v.z - z * v.x), (x * v.y - y * v.x)); + } +}