public void SubdividingGroupWithTooFewChildren() { var s1 = new shape.Sphere(transform.Translation(-2, 0, 0)); var s2 = new shape.Sphere(transform.Translation(2, 1, 0)); var s3 = new shape.Sphere(transform.Translation(2, -1, 4)); var subgroup = new shape.Group(new List <shape.Shape>() { s1, s2, s3 }); var s4 = new shape.Sphere(); var g = new shape.Group(new List <shape.Shape>() { subgroup, s4 }); g.Divide(3); Assert.Equal(subgroup, g[0]); Assert.Equal(s4, g[1]); var sg = (g[0] as shape.Group); Assert.Equal(2, sg.Count()); Assert.IsType <shape.Group>(sg[0]); Assert.Single((sg[0] as shape.Group).Children); Assert.Equal(s1, (sg[0] as shape.Group)[0]); Assert.IsType <shape.Group>(sg[1]); Assert.Equal(2, (sg[1] as shape.Group).Count()); Assert.Equal(new List <shape.Shape>() { s2, s3 }, (sg[1] as shape.Group).Children); }
public void SubdividingGroupPartitionsItsChildren() { var s1 = new shape.Sphere(transform.Translation(-2, -2, 0)); var s2 = new shape.Sphere(transform.Translation(-2, 2, 0)); var s3 = new shape.Sphere(transform.Scaling(4, 4, 4)); var g = new shape.Group(new List <shape.Shape>() { s1, s2, s3 }); g.Divide(1); Assert.Equal(s3, g[0]); var subgroup = g[1]; Assert.IsType <shape.Group>(subgroup); var sg = subgroup as shape.Group; Assert.Equal(2, sg.Count()); Assert.IsType <shape.Group>(sg[0]); Assert.Single((sg[0] as shape.Group).Children); Assert.Equal(s1, (sg[0] as shape.Group)[0]); Assert.IsType <shape.Group>(sg[1]); Assert.Single((sg[1] as shape.Group).Children); Assert.Equal(s2, (sg[1] as shape.Group)[0]); }
public void SphereBoundingBox() { var s = new shape.Sphere(); var box = s.Bounds(); Assert.Equal(pt.Point(-1, -1, -1), box.Minimum); Assert.Equal(pt.Point(1, 1, 1), box.Maximum); }
public void StripesWithObjectTransformation() { var obj = new shapes.Sphere(tf.Scaling(2, 2, 2)); var pattern = Pattern.GetStripePattern(RTF.Color.White, RTF.Color.Black); RTF.Color c = pattern.AtObject(obj, pt.Point(1.5, 0, 0)); Assert.Equal(RTF.Color.White, c); }
public void PatternWithTransformationObject() { var s = new shapes.Sphere(tf.Scaling(2, 2, 2)); var pattern = new TestPattern(); var c = pattern.AtObject(s, pt.Point(2, 3, 4)); Assert.Equal(new RTF.Color(1, 1.5, 2), c); }
public void QueryingShapesBoundingBoxInParentSpace() { var sphere = new shape.Sphere() { Transform = transform.Translation(1, -3, 5) * transform.Scaling(0.5, 2, 4) }; var box = sphere.ParentSpaceBounds(); Assert.Equal(pt.Point(0.5, -5, 1), box.Minimum); Assert.Equal(pt.Point(1.5, -1, 9), box.Maximum); }
public void CSGCreatedWithOperationAndTwoShapes() { var s1 = new shape.Sphere(); var s2 = new shape.Cube(); var c = new shape.CSG(shape.Operation.Union, s1, s2); Assert.Equal(shape.Operation.Union, c.Operation); Assert.Equal(s1, c.Left); Assert.Equal(s2, c.Right); Assert.Equal(c, s1.Parent); Assert.Equal(c, s2.Parent); }
public void IntersectingATransformedGroup() { var g = new shape.Group(transform.Scaling(2, 2, 2)); var s = new shape.Sphere(transform.Translation(5, 0, 0)); g.Add(s); var r = new Ray(pt.Point(10, 0, -10), pt.Vector(0, 0, 1)); var xs = g.Intersect(r); Assert.Equal(2, xs.Count()); }
public void PatternWithTransformationObjectAndPattern() { var s = new shapes.Sphere(tf.Scaling(2, 2, 2)); var pattern = new TestPattern() { Transform = tf.Translation(0.5, 1, 1.5) }; var c = pattern.AtObject(s, pt.Point(2.5, 3, 3.5)); Assert.Equal(new RTF.Color(0.75, 0.5, 0.25), c); }
public void RayHitsCSGObject() { var s1 = new shape.Sphere(); var s2 = new shape.Sphere(transform.Translation(0, 0, 0.5)); var c = new shape.CSG(shape.Operation.Union, s1, s2); var r = new Ray(pt.Point(0, 0, -5), pt.Vector(0, 0, 1)); var xs = c.Intersect(r); Assert.Equal(2, xs.Count()); Assert.Equal(4, xs[0].T); Assert.Equal(s1, xs[0].Object); Assert.Equal(6.5, xs[1].T); Assert.Equal(s2, xs[1].Object); }
public void ConvertingNormalFromObjectToWorldSpace() { var g1 = new shape.Group(transform.RotationY(Math.PI / 2)); var g2 = new shape.Group(transform.Scaling(1, 2, 3)); g1.Add(g2); var s = new shape.Sphere(transform.Translation(5, 0, 0)); g2.Add(s); var value = Math.Sqrt(3) / 3; var n = s.NormalToWorld(pt.Vector(value, value, value)); CustomAssert.Equal(pt.Vector(0.2857, 0.4286, -0.8571), n, 4); }
public void FindingNormalOnChildObject() { var g1 = new shape.Group(transform.RotationY(Math.PI / 2)); var g2 = new shape.Group(transform.Scaling(1, 2, 3)); g1.Add(g2); var s = new shape.Sphere(transform.Translation(5, 0, 0)); g2.Add(s); var n = s.NormalAt(pt.Point(1.7311, 1.1547, -5.5774)); //TODO precision error CustomAssert.Equal(pt.Vector(0.2856, 0.4286, -0.8572), n, 4); }
public void ConvertingPointFromWorldToObjectSpace() { var g1 = new shape.Group(transform.RotationY(Math.PI / 2)); var g2 = new shape.Group(transform.Scaling(2, 2, 2)); g1.Add(g2); var s = new shape.Sphere(transform.Translation(5, 0, 0)); g2.Add(s); var p = s.WorldToObject(pt.Point(-2, 0, -10)); CustomAssert.Equal(pt.Point(0, 0, -1), p, 5); }
public void SubGroupFromListChildren() { var s1 = new shape.Sphere(); var s2 = new shape.Sphere(); var g = new shape.Group(); var list = new List <shape.Shape>() { s1, s2 }; g.Subgroup(list); Assert.Single(g.Children); Assert.IsType <shape.Group>(g.Children[0]); Assert.Equal(list, (g.Children[0] as shape.Group).Children); }
public void PartitioningGroupChildren() { var s1 = new shape.Sphere(transform.Translation(-2, 0, 0)); var s2 = new shape.Sphere(transform.Translation(2, 0, 0)); var s3 = new shape.Sphere(); var g = new shape.Group(); g.Add(new List <shape.Shape>() { s1, s2, s3 }); (List <shape.Shape> left, List <shape.Shape> right) = g.Partition(); Assert.Equal(1, g.Count()); Assert.Single(left); Assert.Equal(s1, left[0]); Assert.Single(right); Assert.Equal(s2, right[0]); }
public void IntersectingRayWithNonemptyGroup() { var g = new shape.Group(); var s1 = new shape.Sphere(); var s2 = new shape.Sphere(transform.Translation(0, 0, -3)); var s3 = new shape.Sphere(transform.Translation(5, 0, 0)); g.Add(s1); g.Add(s2); g.Add(s3); var r = new Ray(pt.Point(0, 0, -5), pt.Vector(0, 0, 1)); var xs = g.Intersect(r); Assert.Equal(4, xs.Count()); Assert.Equal(s2, xs[0].Object); Assert.Equal(s2, xs[1].Object); Assert.Equal(s1, xs[2].Object); Assert.Equal(s1, xs[3].Object); }
public void FilteringListIntersections(string op, int x0, int x1) { var operation = (shape.Operation)Enum.Parse(typeof(shape.Operation), op); var s1 = new shape.Sphere(); var s2 = new shape.Cube(); var c = new shape.CSG(operation, s1, s2); var xs = Intersection.Intersections( new Intersection(1, s1), new Intersection(2, s2), new Intersection(3, s1), new Intersection(4, s2) ); List <Intersection> result = c.FilterIntersections(xs); Assert.Equal(2, result.Count); Assert.Equal(xs[x0], result[0]); Assert.Equal(xs[x1], result[1]); }
private void IceCreamButton_Click(object sender, RoutedEventArgs e) { List <shapes.Shape> shapes = new List <shapes.Shape>(); var a = new patterns.Stripe(RTF.Color.Maroon, RTF.Color.White); var cone = new shapes.Cone() { Transform = transform.Scaling(0.5, 1, 0.5), Material = new RTF.Material() { Pattern = a, Specular = 0 }, Maximum = 3, Minimum = 0 }; shapes.Add(cone); var strawberry = new shapes.Sphere() { Transform = transform.Scaling(2, 2, 2) * transform.Translation(0, 2, 0), Material = new RTF.Material() { Pattern = new patterns.Perturbed(new patterns.Stripe(RTF.Color.Pink, RTF.Color.Red)), Reflective = 0.8, Shininess = 200 } }; shapes.Add(strawberry); var watch = System.Diagnostics.Stopwatch.StartNew(); var canvas = CreateWorld(shapes); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; canvas.SaveAsPPMFile(FolderPath.Text + $"\\IceCream[{elapsedMs}ms].ppm"); }
public void ShadeHitReflectiveTransparentMaterial() { var w = World.Default(); var floor = new shape.Plane { Transform = transform.Translation(0, -1, 0), Material = new Material() { Reflective = 0.5, Transparency = 0.5, RefractiveIndex = 1.5 } }; w.Objects.Add(floor); var ball = new shape.Sphere { Transform = transform.Translation(0, -3.5, -0.5), Material = new Material() { Color = c.Red, Ambient = 0.5 } }; w.Objects.Add(ball); var r = new Ray( pt.Point(0, 0, -3), pt.Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)); var xs = Intersection.Intersections( new Intersection(Math.Sqrt(2), floor)); var comps = Computation.PrepareComputations(xs[0], r, xs); var color = w.ShadeHit(comps, 5); //TODO var exp = new c(0.93391, 0.69643, 0.69243); var exp = new c(0.93392, 0.69644, 0.69243); CustomAssert.Equal(exp, color, 5); }
public void GroupHasBoundingBoxContainsItsChildren() { var s = new shape.Sphere() { Transform = transform.Translation(2, 5, -3) * transform.Scaling(2, 2, 2) }; var c = new shape.Cylinder() { Minimum = -2, Maximum = 2, Transform = transform.Translation(-4, -1, 4) * transform.Scaling(0.5, 1, 0.5) }; var shape = new shape.Group(); shape.Add(s); shape.Add(c); var box = shape.Bounds(); Assert.Equal(pt.Point(-4.5, -3, -5), box.Minimum); Assert.Equal(pt.Point(4, 7, 4.5), box.Maximum); }
/* *- add: camera * width: 400 * height: 400 * field-of-view: 0.5 * from: [0, 0, -5] * to: [0, 0, 0] * up: [0, 1, 0] * * - add: light * at: [-10, 10, -10] * intensity: [1, 1, 1] * * - add: sphere * material: * pattern: * type: map * mapping: spherical * uv_pattern: * type: checkers * width: 20 * height: 10 * colors: * - [0, 0.5, 0] * - [1, 1, 1] * ambient: 0.1 * specular: 0.4 * shininess: 10 * diffuse: 0.6 */ private void CheckersOnSphere_Click(object sender, RoutedEventArgs e) { var camera = new RTF.Camera(400, 400, 0.5) { Transform = transform.ViewTransform( point.Point(0, 0, -5), point.Point(0, 0, 0), point.Vector(0, 1, 0)) }; var light = new RTF.Light(point.Point(-10, 10, -10), RTF.Color.White); var checker = new UV.Checker(20, 10, new RTF.Color(0, 0.5, 0), new RTF.Color(1, 1, 1)); var pattern = new patterns.TextureMap(UV.Pattern.SphericalMap, checker); var sphere = new shapes.Sphere() { Material = new RTF.Material() { Pattern = pattern, Ambient = 0.1, Specular = 0.4, Shininess = 10, Diffuse = 0.6 } }; var world = new RTF.World(); world.Lights.Add(light); world.Objects.Add(sphere); var watch = System.Diagnostics.Stopwatch.StartNew(); var canvas = RTF.Canvas.Render(camera, world); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; canvas.SaveAsPPMFile(FolderPath.Text + $"\\TextureMap_2DCheckers3DSphere[{elapsedMs}ms].ppm"); }
private void LancellottiChapel_Click(object sender, RoutedEventArgs e) { var light = new RTF.Light(point.Point(0, 100, 0), RTF.Color.White); var camera = new RTF.Camera(800, 400, 1.2) { Transform = transform.ViewTransform( point.Point(0, 0, 0), point.Point(0, 0, 5), point.Vector(0, 1, 0)) }; var sphere = new shapes.Sphere() { Transform = transform.Translation(0, 0, 5) * transform.Scaling(0.75, 0.75, 0.75), Material = new RTF.Material() { Diffuse = 0.4, Specular = 0.6, Shininess = 20, Reflective = 0.6, Ambient = 0 } }; var negx = new List <string>(); var negy = new List <string>(); var negz = new List <string>(); var posx = new List <string>(); var posy = new List <string>(); var posz = new List <string>(); try { using (StreamReader sr = new StreamReader(@".\Files\negx.ppm")) { string line; while ((line = sr.ReadLine()) != null) { negx.Add(line); } } using (StreamReader sr = new StreamReader(@".\Files\negy.ppm")) { string line; while ((line = sr.ReadLine()) != null) { negy.Add(line); } } using (StreamReader sr = new StreamReader(@".\Files\negz.ppm")) { string line; while ((line = sr.ReadLine()) != null) { negz.Add(line); } } using (StreamReader sr = new StreamReader(@".\Files\posx.ppm")) { string line; while ((line = sr.ReadLine()) != null) { posx.Add(line); } } using (StreamReader sr = new StreamReader(@".\Files\posy.ppm")) { string line; while ((line = sr.ReadLine()) != null) { posy.Add(line); } } using (StreamReader sr = new StreamReader(@".\Files\posz.ppm")) { string line; while ((line = sr.ReadLine()) != null) { posz.Add(line); } } } catch (FileNotFoundException ex) { throw ex; } var pattern = new UV.Cube(new UV.Image(RTF.Canvas.CanvasFromPPM(negx)), new UV.Image(RTF.Canvas.CanvasFromPPM(posx)), new UV.Image(RTF.Canvas.CanvasFromPPM(posz)), new UV.Image(RTF.Canvas.CanvasFromPPM(negz)), new UV.Image(RTF.Canvas.CanvasFromPPM(posy)), new UV.Image(RTF.Canvas.CanvasFromPPM(negy))); var cube = new shapes.Sphere() { Transform = transform.Scaling(1000, 1000, 1000), Material = new RTF.Material() { Pattern = pattern, Diffuse = 0, Specular = 0, Ambient = 1 } }; var world = new RTF.World { Lights = new List <RTF.Light>() { light }, Objects = new List <shapes.Shape>() { sphere, cube } }; var watch = System.Diagnostics.Stopwatch.StartNew(); var finalCanvas = RTF.Canvas.Render(camera, world); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; finalCanvas.SaveAsPPMFile(FolderPath.Text + $"\\TextureMap_LancellottiChapel[{elapsedMs}ms].ppm"); }
public RTF.Canvas CreateCircle() { var floor = new shapes.Sphere() { Transform = transform.Scaling(10, 0.01, 10), Material = new RTF.Material() { Color = new RTF.Color(1, 0.9, 0.9), Specular = 0 } }; var leftWall = new shapes.Sphere() { Transform = transform.Translation(0, 0, 5) * transform.RotationY(-Math.PI / 4) * transform.RotationX(Math.PI / 2) * transform.Scaling(10, 0.01, 10), Material = floor.Material }; var rightWall = new shapes.Sphere() { Transform = transform.Translation(0, 0, 5) * transform.RotationY(Math.PI / 4) * transform.RotationX(Math.PI / 2) * transform.Scaling(10, 0.01, 10), Material = floor.Material }; var middle = new shapes.Sphere() { Transform = transform.Translation(-0.5, 1, 0.5), Material = new RTF.Material(new RTF.Color(0.1, 1, 0.5), 0.7, 0.3) }; var right = new shapes.Sphere() { Transform = transform.Translation(1.5, 0.5, -0.5) * transform.Scaling(0.5, 0.5, 0.5), Material = new RTF.Material(new RTF.Color(0.5, 1, 0.1), 0.7, 0.3) }; var left = new shapes.Sphere() { Transform = transform.Translation(-1.5, 0.33, -0.75) * transform.Scaling(0.33, 0.33, 0.33), Material = new RTF.Material(new RTF.Color(1, 0.8, 0.1), 0.7, 0.3) }; var world = new RTF.World { Lights = new List <RTF.Light>() { new RTF.Light(point.Point(-10, 10, -10), RTF.Color.White) }, Objects = new List <shapes.Shape>() { floor, leftWall, rightWall, right, middle, right, left } }; var camera = new RTF.Camera(100, 50, Math.PI / 3) { Transform = transform.ViewTransform( point.Point(0, 1.5, -5), point.Point(0, 1, 0), point.Vector(0, 1, 0)) }; return(RTF.Canvas.Render(camera, world)); }
private void Earth_Click(object sender, RoutedEventArgs e) { var file = new List <string>(); try { using (StreamReader sr = new StreamReader(@".\Files\EarthMap.ppm")) { string line; while ((line = sr.ReadLine()) != null) { file.Add(line); } } } catch (FileNotFoundException ex) { throw ex; } var canvas = RTF.Canvas.CanvasFromPPM(file); var pattern = new UV.Image(canvas); var light = new RTF.Light(point.Point(-100, 100, -100), RTF.Color.White); var camera = new RTF.Camera(800, 400, 0.8) { Transform = transform.ViewTransform( point.Point(1, 2, -10), point.Point(0, 1.1, 0), point.Vector(0, 1, 0)) }; var cylinder = new shapes.Cylinder() { Minimum = 0, Maximum = 0.1, Closed = true, Material = new RTF.Material() { Color = RTF.Color.White, Diffuse = 0.2, Specular = 0, Ambient = 0, Reflective = 0.1 } }; var plane = new shapes.Plane() { Material = new RTF.Material() { Color = RTF.Color.White, Diffuse = 0.1, Specular = 0, Ambient = 0, Reflective = 0.4 } }; var sphere = new shapes.Sphere() { Transform = transform.Translation(0, 1.1, 0) * transform.RotationY(1.9), Material = new RTF.Material() { Pattern = new patterns.TextureMap(UV.Pattern.SphericalMap, pattern), Diffuse = 0.9, Specular = 0.1, Shininess = 10, Ambient = 0.1 } }; var world = new RTF.World { Lights = new List <RTF.Light>() { light }, Objects = new List <shapes.Shape>() { cylinder, plane, sphere } }; var watch = System.Diagnostics.Stopwatch.StartNew(); var finalCanvas = RTF.Canvas.Render(camera, world); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; finalCanvas.SaveAsPPMFile(FolderPath.Text + $"\\TextureMap_Earth[{elapsedMs}ms].ppm"); }