public void ShadeHitReflectiveMaterial()
        {
            var w     = World.Default();
            var shape = new shape.Plane()
            {
                Material = new Material()
                {
                    Reflective = 0.5
                },
                Transform = transform.Translation(0, -1, 0)
            };

            w.Objects.Add(shape);

            var r = new Ray(
                pt.Point(0, 0, -3),
                pt.Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2));

            var i     = new Intersection(Math.Sqrt(2), shape);
            var comps = Computation.PrepareComputations(i, r);

            var color = w.ShadeHit(comps);
            //TODO var exp = new c(0.87677, 0.92436, 0.82918);
            var exp = new c(0.87677, 0.92436, 0.82919);

            CustomAssert.Equal(exp, color, 5);
        }
        public RTF.Canvas CreateWorld(List <shapes.Shape> shapes)
        {
            var ceilling = new shapes.Plane()
            {
                Material = new RTF.Material()
                {
                    Color    = new RTF.Color(1, 0.9, 0.9),
                    Specular = 0
                }
            };

            shapes.Add(ceilling);

            var world = new RTF.World
            {
                Lights = new List <RTF.Light>()
                {
                    new RTF.Light(point.Point(-10, 10, -10), RTF.Color.White)
                },
                Objects = shapes
            };

            var camera = new RTF.Camera(400, 200, 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));
        }
        public void ReflectedColorForReflectiveMaterial()
        {
            var w     = World.Default();
            var shape = new shape.Plane()
            {
                Material = new Material()
                {
                    Reflective = 0.5
                },
                Transform = transform.Translation(0, -1, 0)
            };

            w.Objects.Add(shape);

            var r = new Ray(
                pt.Point(0, 0, -3),
                pt.Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2));

            var i     = new Intersection(Math.Sqrt(2), shape);
            var comps = Computation.PrepareComputations(i, r);

            var color = w.ReflectedColor(comps);
            //TODO var exp = new c(0.19032, 0.23790, 0.14274);
            var exp = new c(0.19035, 0.23793, 0.14276);

            CustomAssert.Equal(exp, color, 5);
        }
        public void ColorAtMutuallyReflectiveSurfaces()
        {
            var w = new World
            {
                Lights = new System.Collections.Generic.List <Light>()
                {
                    new Light(pt.Point(0, 0, 0), c.White)
                }
            };

            var lower = new shape.Plane();

            lower.Material.Reflective = 1;
            lower.Transform           = transform.Translation(0, -1, 0);

            var upper = new shape.Plane();

            upper.Material.Reflective = 1;
            upper.Transform           = transform.Translation(0, 1, 0);

            w.Objects.Add(lower);
            w.Objects.Add(upper);

            var r = new Ray(pt.Point(0, 0, 0), pt.Vector(0, 1, 0));

            w.ColorAt(r);
        }
        public void PlaneBoundingBox()
        {
            var s   = new shape.Plane();
            var box = s.Bounds();

            Assert.Equal(pt.Point(double.NegativeInfinity, 0, double.NegativeInfinity), box.Minimum);
            Assert.Equal(pt.Point(double.PositiveInfinity, 0, double.PositiveInfinity), box.Maximum);
        }
        public void IntersectWithCoplanarRay()
        {
            var p = new shapes.Plane();
            var r = new RTF.Ray(
                pt.Point(0, 0, 0), pt.Vector(0, 0, 1));
            var xs = p.LIntersect(r);

            Assert.Empty(xs);
        }
        public void NormalPlaneConstantEverywhere()
        {
            var p  = new shapes.Plane();
            var n1 = p.LNormalAt(pt.Point(0, 0, 0));
            var n2 = p.LNormalAt(pt.Point(10, 0, -10));
            var n3 = p.LNormalAt(pt.Point(-5, 0, 150));

            Assert.Equal(pt.Vector(0, 1, 0), n1);
            Assert.Equal(pt.Vector(0, 1, 0), n2);
            Assert.Equal(pt.Vector(0, 1, 0), n3);
        }
        public void RayIntersectionPlaneFromBelow()
        {
            var p = new shapes.Plane();
            var r = new RTF.Ray(
                pt.Point(0, -1, 0), pt.Vector(0, 1, 0));
            var xs = p.LIntersect(r);

            Assert.NotEmpty(xs);
            Assert.Equal(1, xs[0].T);
            Assert.Equal(p, xs[0].Object);
        }
        public void PrecomputingReflectorVector()
        {
            var shape = new shape.Plane();
            var r     = new Ray(
                pt.Point(0, 1, -1),
                pt.Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2));
            var i     = new Intersection(Math.Sqrt(2), shape);
            var comps = Computation.PrepareComputations(i, r);

            var e = pt.Vector(0, Math.Sqrt(2) / 2, Math.Sqrt(2) / 2);

            Assert.Equal(e, comps.RelflectV);
        }
        public void ReflectedColorMaximumRecursiveDepth()
        {
            var w     = World.Default();
            var shape = new shape.Plane();

            shape.Material.Reflective = 0.5;
            shape.Transform           = transform.Translation(0, -1, 0);

            w.Objects.Add(shape);

            var r = new Ray(
                pt.Point(0, 0, -3),
                pt.Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2));
            var i = new Intersection(Math.Sqrt(2), shape);

            var comps = Computation.PrepareComputations(i, r);
            var color = w.ReflectedColor(comps, 0);

            Assert.Equal(c.Black, color);
        }
        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);
        }
        /*
         * - add: camera
         * width: 400
         * height: 400
         * field-of-view: 0.5
         * from: [1, 2, -5]
         * to: [0, 0, 0]
         * up: [0, 1, 0]
         *
         * - add: light
         * at: [-10, 10, -10]
         * intensity: [1, 1, 1]
         *
         * - add: plane
         * material:
         *  pattern:
         *    type: map
         *    mapping: planar
         *    uv_pattern:
         *      type: checkers
         *      width: 2
         *      height: 2
         *      colors:
         *        - [0, 0.5, 0]
         *        - [1, 1, 1]
         *  ambient: 0.1
         *  specular: 0
         *  diffuse: 0.9
         */
        private void CheckersOnPlanar_Click(object sender, RoutedEventArgs e)
        {
            var camera = new RTF.Camera(400, 400, 0.5)
            {
                Transform = transform.ViewTransform(
                    point.Point(1, 2, -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(2, 2, new RTF.Color(0, 0.5, 0), new RTF.Color(1, 1, 1));
            var pattern = new patterns.TextureMap(UV.Pattern.PlanarMap, checker);
            var plane   = new shapes.Plane()
            {
                Material = new RTF.Material()
                {
                    Pattern  = pattern,
                    Ambient  = 0.1,
                    Specular = 0,
                    Diffuse  = 0.9
                }
            };

            var world = new RTF.World();

            world.Lights.Add(light);
            world.Objects.Add(plane);

            var watch  = System.Diagnostics.Stopwatch.StartNew();
            var canvas = RTF.Canvas.Render(camera, world);

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            canvas.SaveAsPPMFile(FolderPath.Text + $"\\TextureMap_2DCheckersPlanar[{elapsedMs}ms].ppm");
        }
        public RTF.Canvas CreateWorld()
        {
            var camera = new RTF.Camera(100, 100, 0.785)
            {
                Transform = transform.ViewTransform(
                    point.Point(-6, 6, -10),
                    point.Point(6, 0, 6),
                    point.Vector(-0.45, 1, 0))
            };

            var light1 = new RTF.Light(point.Point(50, 100, -50), RTF.Color.White);
            var light2 = new RTF.Light(point.Point(-400, 50, -10), RTF.Color.White);

            var whiteMaterial = new RTF.Material()
            {
                Color = RTF.Color.White,
                Diffuse = 0.7,
                Ambient = 0.1,
                Specular = 0,
                Reflective = 0.1
            };
            var blueMaterial = new RTF.Material()
            {
                Color = new RTF.Color(0.537, 0.831, 0.914),
                Diffuse = 0.7,
                Ambient = 0.1,
                Specular = 0,
                Reflective = 0.1
            };
            var redMaterial = new RTF.Material()
            {
                Color = new RTF.Color(0.941, 0.322, 0.388),
                Diffuse = 0.7,
                Ambient = 0.1,
                Specular = 0,
                Reflective = 0.1
            };
            var purpleMaterial = new RTF.Material()
            {
                Color = new RTF.Color(0.373, 0.404, 0.550),
                Diffuse = 0.7,
                Ambient = 0.1,
                Specular = 0,
                Reflective = 0.1
            };

            var standardTransform = transform.Translation(1, -1, 1) * transform.Scaling(0.5, 0.5, 0.5);
            var largeObject = standardTransform * transform.Scaling(3.5, 3.5, 3.5);
            var mediumObject = standardTransform * transform.Scaling(3, 3, 3);
            var smallObject = standardTransform * transform.Scaling(2, 2, 2);

            var whitebackdrop = new shapes.Plane()
            {
                Material = new RTF.Material()
                {
                    Color = RTF.Color.White,
                    Ambient = 1,
                    Diffuse = 0,
                    Specular = 0
                },
                Transform = transform.RotationX(Math.PI / 2) * transform.Translation(0, 0, 500)
            };

            var group = new shapes.Group(
                new List<shapes.Shape>()
                {
                    new shapes.Sphere()
                    {
                        Material = new RTF.Material()
                        {
                            Color = purpleMaterial.Color,
                            Diffuse = 0.2,
                            Ambient = 0,
                            Specular = 1,
                            Shininess = 200,
                            Reflective = 0.7,
                            Transparency = 0.7,
                            RefractiveIndex = 1.5
                        },
                        Transform = largeObject
                    },
                    new shapes.Cube(whiteMaterial, mediumObject * transform.Translation(4, 0, 0)),
                    new shapes.Cube(blueMaterial, largeObject * transform.Translation(8.5, 1.5, -0.5)),
                    new shapes.Cube(redMaterial, largeObject * transform.Translation(0, 0, 4)),
                    new shapes.Cube(whiteMaterial, smallObject * transform.Translation(4, 0, 4)),
                    new shapes.Cube(purpleMaterial, mediumObject * transform.Translation(7.5, 0.5, 4)),
                    new shapes.Cube(whiteMaterial, mediumObject * transform.Translation(-0.25, 0.25, 8)),
                    new shapes.Cube(blueMaterial,  largeObject * transform.Translation(4, 1, 7.5)),
                    new shapes.Cube(redMaterial,  mediumObject * transform.Translation(10, 2, 7.5)),
                    new shapes.Cube(whiteMaterial,  smallObject * transform.Translation(8, 2, 12)),
                    new shapes.Cube(whiteMaterial,  smallObject * transform.Translation(20, 1, 9)),
                    new shapes.Cube(blueMaterial,  largeObject * transform.Translation(-0.5, -5, 0.25)),
                    new shapes.Cube(redMaterial,  largeObject * transform.Translation(4, -4, 0)),
                    new shapes.Cube(whiteMaterial,  largeObject * transform.Translation(8.5, -4, 0)),
                    new shapes.Cube(whiteMaterial,  largeObject * transform.Translation(0, -4, 4)),
                    new shapes.Cube(purpleMaterial,  largeObject * transform.Translation(-0.5, -4.5, 8)),
                    new shapes.Cube(whiteMaterial,  largeObject * transform.Translation(0, -8, 4)),
                    new shapes.Cube(whiteMaterial,  largeObject * transform.Translation(-0.5, -8.5, 8))
                }
            );


            var world = new RTF.World()
            {
                Lights = new List<RTF.Light>() { light1, light2 },

                Objects = new List<shapes.Shape>()
                {
                    group, whitebackdrop
                }
            };

            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");
        }