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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #8
0
        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());
        }
Beispiel #9
0
        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);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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]);
        }
Beispiel #16
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]);
        }
Beispiel #18
0
        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");
        }
Beispiel #23
0
        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");
        }