예제 #1
0
        static void Main(string[] args)
        {
            Point  p   = new Point(0, 1, 0);
            Matrix hq  = MatrixOps.CreateRotationXTransform(Math.PI / 4.0);
            Matrix inv = (Matrix)hq.Inverse();

            Console.WriteLine(hq.ToString());
            Console.WriteLine(inv.ToString());
            Console.WriteLine(p.Transform(inv).ToString());
            Matrix t = MatrixOps.CreateTranslationTransform(5, -3, 2);

            p = new Point(-3, 4, 5);
            Point pt  = p.Transform(t);
            bool  foo = (p.Transform(t).Equals(new Point(2, 1, 7)));

            RayTracerLib.Vector a  = new RayTracerLib.Vector(1, 2, 3);
            RayTracerLib.Vector b  = new RayTracerLib.Vector(2, 3, 4);
            RayTracerLib.Vector ab = a.Cross(b);
            RayTracerLib.Vector ba = b.Cross(a);
            bool foo1 = (a.Cross(b).IsEqual(new RayTracerLib.Vector(-1, 2, -1)));
            bool foo2 = (b.Cross(a).IsEqual(new RayTracerLib.Vector(1, -2, 1)));

            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }
예제 #2
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Calculates the camera Field of View (FOV) such that it will encompass the entire group provided. </summary>
        ///
        /// <remarks>   Kemp, 1/6/2019. </remarks>
        ///
        /// <param name="cameraPoint">      The camera point - where it is. </param>
        /// <param name="CameraPointsAt">   The camera points at - what it's pointing at. </param>
        /// <param name="g">                A Group that the camera is pointing at. </param>
        ///
        /// <returns>   The calculated camera FOV. </returns>
        ///-------------------------------------------------------------------------------------------------

        static double CalcCameraFOV(Point cameraPoint, Point CameraPointsAt, Group g)
        {
            RayTracerLib.Vector CameraVect = (cameraPoint - CameraPointsAt).Normalize();
            Point maxXfront = new Point(g.Bounds.MaxCorner.X, CameraPointsAt.Y, g.Bounds.MinCorner.Z);
            Point maxXrear  = new Point(g.Bounds.MaxCorner.X, CameraPointsAt.Y, g.Bounds.MaxCorner.Z);
            Point maxX      = ((CameraVect.Dot((cameraPoint - maxXfront).Normalize()) < CameraVect.Dot((cameraPoint - maxXrear).Normalize()))) ? maxXfront : maxXrear;

            Point minXfront = new Point(g.Bounds.MinCorner.X, CameraPointsAt.Y, g.Bounds.MinCorner.Z);
            Point minXrear  = new Point(g.Bounds.MinCorner.X, CameraPointsAt.Y, g.Bounds.MaxCorner.Z);
            Point minX      = ((CameraVect.Dot((cameraPoint - minXfront).Normalize()) < CameraVect.Dot((cameraPoint - minXrear).Normalize()))) ? minXfront : minXrear;

            Point maxYfront = new Point(CameraPointsAt.X, g.Bounds.MaxCorner.Y, g.Bounds.MinCorner.Z);
            Point maxYrear  = new Point(CameraPointsAt.X, g.Bounds.MaxCorner.Y, g.Bounds.MaxCorner.Z);
            Point maxY      = ((CameraVect.Dot((cameraPoint - maxYfront).Normalize()) < CameraVect.Dot((cameraPoint - maxYrear).Normalize()))) ? maxYfront : maxYrear;

            Point minYfront = new Point(CameraPointsAt.X, g.Bounds.MinCorner.Y, g.Bounds.MinCorner.Z);
            Point minYrear  = new Point(CameraPointsAt.X, g.Bounds.MinCorner.Y, g.Bounds.MaxCorner.Z);
            Point minY      = ((CameraVect.Dot((cameraPoint - minYfront).Normalize()) < CameraVect.Dot((cameraPoint - minYrear).Normalize()))) ? minYfront : minYrear;

            double cameraFOVCos = Math.Min(CameraVect.Dot((cameraPoint - maxX).Normalize()), CameraVect.Dot((cameraPoint - minX).Normalize()));

            cameraFOVCos = Math.Min(cameraFOVCos, CameraVect.Dot((cameraPoint - maxY).Normalize()));
            cameraFOVCos = Math.Min(cameraFOVCos, CameraVect.Dot((cameraPoint - minY).Normalize()));
            return(Math.Acos(cameraFOVCos) * 2);
        }
예제 #3
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Main entry-point for this application. </summary>
        ///
        /// <remarks>   Kemp, 12/5/2018. </remarks>
        ///
        /// <param name="args"> An array of command-line argument strings. </param>
        ///-------------------------------------------------------------------------------------------------

        static void Main(string[] args)
        {
            /// where we are looking from
            Point eyep = new Point(0, 0, -5);

            /// define the sphere
            Sphere s = new Sphere();

            s.Material       = new Material();
            s.Material.Color = new Color(1, 0.2, 1);
            //s.Transform = RTMatrixOps.Scaling(1, 0.5, 1);
            s.Material.Pattern           = new Checked3DPattern(new Color(0, 0, 0), new Color(1, 1, 1));
            s.Material.Pattern.Transform = MatrixOps.CreateScalingTransform(0.2, 0.2, 0.2);
            s.Transform = MatrixOps.CreateRotationYTransform(Math.PI / 4);

            /// define the light
            Point      lightPos   = new Point(-10, 10, -10);
            Color      lightColor = new Color(1, 1, 1);
            LightPoint light      = new LightPoint(lightPos, lightColor);

            /// Calculate canvas size and resolution
            const uint canvasResolution = 256;
            const uint canvasZ          = 10;

            RayTracerLib.Vector tangentRay = (new Point(0, 1, 0) - eyep).Normalize();
            double canvasSize   = ((tangentRay * (canvasZ - eyep.Z)).Y * 1.1) * 2;
            Point  canvasOrigin = new Point(-canvasSize / 2.0, -canvasSize / 2.0, canvasZ);
            Canvas c            = new Canvas(canvasResolution, canvasResolution);

            //now loop collecting canvas points.
            Point canvaspoint = new Point(0, 0, 10);
            Color red         = new Color(255, 0, 0);

            for (int iy = 0; iy < canvasResolution; iy++)
            {
                for (int ix = 0; ix < canvasResolution; ix++)
                {
                    canvaspoint.X = (double)ix * canvasSize / canvasResolution + canvasOrigin.X;
                    canvaspoint.Y = (double)iy * canvasSize / canvasResolution + canvasOrigin.Y;
                    RayTracerLib.Vector rayv = (canvaspoint - eyep).Normalize();
                    Ray r = new Ray(eyep, rayv);
                    List <Intersection> xs = s.Intersect(r);
                    if (xs.Count != 0)
                    {
                        Intersection        hit      = xs[0];
                        Point               hitpoint = r.Position(hit.T);
                        RayTracerLib.Vector normal   = ((Sphere)hit.Obj).NormalAt(hitpoint);
                        Color               phong    = Ops.Lighting(((Sphere)hit.Obj).Material, hit.Obj, light, hitpoint, -rayv, normal);
                        c.WritePixel((uint)ix, (uint)iy, phong);
                    }
                }
            }
            String ppm = c.ToPPM();

            System.IO.File.WriteAllText(@"ToPPM.ppm", ppm);

            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }
예제 #4
0
파일: Program.cs 프로젝트: kemptm/RayTracer
        static void Main(string[] args)
        {
            {
                Sphere s = new Sphere();
                RayTracerLib.Vector n = s.NormalAt(new Point(1, 0, 0));
                bool foo = n.Equals(new RayTracerLib.Vector(1, 0, 0));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                Sphere   s   = new Sphere();
                Material m   = s.Material;
                bool     foo = m.Equals(new Material());

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                Material m        = new Material();
                Point    position = new Point();

                RayTracerLib.Vector eyev    = new RayTracerLib.Vector(0, 0, -1);
                RayTracerLib.Vector normalv = new RayTracerLib.Vector(0, 0, -1);
                Sphere s = new Sphere();

                LightPoint light  = new LightPoint(new Point(0, 0, -10), new Color(1, 1, 1));
                Color      result = Ops.Lighting(m, s, light, position, eyev, normalv);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                Material m        = new Material();
                Point    position = new Point();

                RayTracerLib.Vector eyev    = new RayTracerLib.Vector(0, Math.Sqrt(2) / 2, -Math.Sqrt(2) / 2);
                RayTracerLib.Vector normalv = new RayTracerLib.Vector(0, 0, -1);
                Sphere     s      = new Sphere();
                LightPoint light  = new LightPoint(new Point(0, 0, -10), new Color(1, 1, 1));
                Color      result = Ops.Lighting(m, s, light, position, eyev, normalv);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                //SphereNormalScaled() {
                Sphere s = new Sphere();
                s.Transform = MatrixOps.CreateScalingTransform(1, 1, 1);
                Point p = new Point(0, Math.Sqrt(2) / 2, -Math.Sqrt(2) / 2);
                RayTracerLib.Vector n = s.NormalAt(p);
                bool foo = (n.Equals(new RayTracerLib.Vector(0, 0.97014, -0.24254)));


                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }

            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }
예제 #5
0
파일: Program.cs 프로젝트: kemptm/RayTracer
        static void Main(string[] args)
        {
            Point      light            = new Point(0, 0, -5);
            Sphere     s                = new Sphere();
            const uint canvasResolution = 128;
            const uint canvasZ          = 10;

            RayTracerLib.Vector tangentRay = (new Point(0, 1, 0) - light).Normalize();
            double canvasSize   = ((tangentRay * (canvasZ - light.Z)).Y * 1.1) * 2;
            Point  canvasOrigin = new Point(-canvasSize / 2.0, -canvasSize / 2.0, canvasZ);

            Canvas c = new Canvas(canvasResolution, canvasResolution);

            Point canvaspoint = new Point(0, 0, 10);
            Color red         = new Color(255, 0, 0);

            for (int iy = 0; iy < canvasResolution; iy++)
            {
                for (int ix = 0; ix < canvasResolution; ix++)
                {
                    canvaspoint.X = (double)ix * canvasSize / canvasResolution + canvasOrigin.X;
                    canvaspoint.Y = (double)iy * canvasSize / canvasResolution + canvasOrigin.Y;
                    RayTracerLib.Vector rayv = (canvaspoint - light).Normalize();
                    Ray r = new Ray(light, rayv);
                    List <Intersection> xs = s.Intersect(r);
                    if (xs.Count != 0)
                    {
                        c.WritePixel((uint)ix, (uint)iy, red);
                    }
                }
            }
            String ppm = c.ToPPM();

            System.IO.File.WriteAllText(@"ToPPM.ppm", ppm);

            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }
예제 #6
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Main entry-point for this application. </summary>
        ///
        /// <remarks>   Kemp, 1/18/2019. </remarks>
        ///
        /// <param name="args"> An array of command-line argument strings. </param>
        ///-------------------------------------------------------------------------------------------------

        static void Main(string[] args)
        {
            World defaultWorld = new World();

            defaultWorld.AddLight(new LightPoint(new Point(-10, 10, -10), new Color(1, 1, 1)));

            Sphere s1 = new Sphere();

            s1.Material          = new Material();
            s1.Material.Color    = new Color(0.8, 1.0, 0.6);
            s1.Material.Diffuse  = new Color(0.7, 0.7, 0.7);
            s1.Material.Specular = new Color(0.2, 0.2, 0.2);

            Sphere s2 = new Sphere();

            s2.Transform = MatrixOps.CreateScalingTransform(0.5, 0.5, 0.5);
            defaultWorld.AddObject(s1);
            defaultWorld.AddObject(s2);

            {
                // ColorAtRayMisses
                World world = defaultWorld.Copy();
                Ray   ray   = new Ray(new Point(0, 0, -5), new RayTracerLib.Vector(0, 1, 0));
                Color c     = world.ColorAt(ray);
                bool  foo   = c.Equals(new Color(0, 0, 0));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                // IntersectionShadingInside
                World world = defaultWorld.Copy();
                world.Lights.Clear();
                world.AddLight(new LightPoint(new Point(0, 0.25, 0), new Color(1, 1, 1)));
                Ray                 ray   = new Ray(new Point(0, 0, 0), new RayTracerLib.Vector(0, 0, 1));
                Shape               shape = world.Objects[1];
                Intersection        hit   = new Intersection(0.5, shape);
                List <Intersection> xs    = new List <Intersection>();
                xs.Add(hit);
                hit.Prepare(ray, xs);
                Color c   = hit.Shade(world);
                bool  foo = c.Equals(new Color(0.90498, 0.90498, 0.90498));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                //ColorAtBehindRay() {
                World world = defaultWorld.Copy();
                Shape outer = defaultWorld.Objects[0];
                outer.Material.Ambient = new Color(1, 1, 1);
                Shape inner = defaultWorld.Objects[1];
                inner.Material.Ambient = new Color(1, 1, 1);
                Ray   ray = new Ray(new Point(0, 0, -0.75), new RayTracerLib.Vector(0, 0, 1));
                Color imc = inner.Material.Color;
                Color c   = world.ColorAt(ray);
                bool  foo = world.ColorAt(ray).Equals(imc);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }

            {
                Point from             = new Point(1, 3, 2);
                Point to               = new Point(4, -2, 8);
                RayTracerLib.Vector up = new RayTracerLib.Vector(1, 1, 0);
                Matrix t               = MatrixOps.CreateViewTransform(from, to, up);
                Matrix r               = DenseMatrix.OfArray(new double[, ] {
                    { -0.50709, 0.50709, 0.67612, -2.36643 },
                    { 0.76772, 0.60609, 0.12122, -2.82843 },
                    { -0.35857, 0.59761, -0.71714, 0.0 },
                    { 0.0, 0.0, 0.0, 1.0 }
                });
                bool   foo = t.Equals(r);
                Matrix d   = (Matrix)(t - r);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                Camera c1 = new Camera(200, 125, Math.PI / 2.0);
                Camera c2 = new Camera(125, 200, Math.PI / 2.0);

                bool foo1 = Ops.Equals(c1.PixelSize, 0.01);
                bool foo2 = Ops.Equals(c2.PixelSize, 0.01);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                //objectBetweenLightAndPoint
                World world = defaultWorld.Copy();
                Point p     = new Point(10, -10, 10);
                bool  foo   = p.IsShadowed(world, world.Lights[0]);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                //public void IntersectionOnInside() {
                Ray                 ray   = new Ray(new Point(0, 0, 0), new RayTracerLib.Vector(0, 0, 1));
                Shape               shape = new Sphere();
                Intersection        hit   = new Intersection(1, shape);
                List <Intersection> xs    = new List <Intersection>();
                xs.Add(hit);
                hit.Prepare(ray, xs);
                bool foo1 = hit.Inside;
                bool foo2 = hit.Point.Equals(new Point(0, 0, 1.0001));
                bool foo3 = hit.Eyev.Equals(new RayTracerLib.Vector(0, 0, -1));
                bool foo4 = hit.Normalv.Equals(new RayTracerLib.Vector(0, 0, -1));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                //IntersectionShadingInside
                World world = defaultWorld;
                world.Lights.Clear(); // remove default light.
                world.AddLight(new LightPoint(new Point(0, 0.25, 0), new Color(1, 1, 1)));
                Ray                 ray   = new Ray(new Point(0, 0, 0), new RayTracerLib.Vector(0, 0, 1));
                Shape               shape = world.Objects[1];
                Intersection        hit   = new Intersection(0.5, shape);
                List <Intersection> xs    = new List <Intersection>();
                xs.Add(hit);
                hit.Prepare(ray, xs);
                Color c   = hit.Shade(world);
                bool  foo = c.Equals(new Color(0.90498, 0.90498, 0.90498));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }
예제 #7
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Main entry-point for this application. </summary>
        ///
        /// <remarks>   Kemp, 1/18/2019. </remarks>
        ///
        /// <param name="args"> An array of command-line argument strings. </param>
        ///-------------------------------------------------------------------------------------------------

        static void Main(string[] args)
        {
            World defaultWorld = new World();

            defaultWorld.AddLight(new LightPoint(new Point(-10, 10, -10), new Color(1, 1, 1)));

            Sphere s1 = new Sphere();

            s1.Material          = new Material();
            s1.Material.Color    = new Color(0.8, 1.0, 0.6);
            s1.Material.Diffuse  = new Color(0.7, 0.7, 0.7);
            s1.Material.Specular = new Color(0.2, 0.2, 0.2);

            Sphere s2 = new Sphere();

            s2.Transform = MatrixOps.CreateScalingTransform(0.5, 0.5, 0.5);
            defaultWorld.AddObject(s1);
            defaultWorld.AddObject(s2);
            Color  white = new Color(1, 1, 1);
            Color  black = new Color(0, 0, 0);
            Sphere s     = new Sphere();


            {
                Material m = new Material();
                m.Pattern   = new StripePattern(white, black);
                m.Ambient   = new Color(1, 1, 1);
                m.Diffuse   = new Color(0, 0, 0);
                m.Specular  = new Color(0, 0, 0);
                m.Shininess = 0;
                RayTracerLib.Vector eyev    = new RayTracerLib.Vector(0, 0, -1);
                RayTracerLib.Vector normalv = new RayTracerLib.Vector(0, 0, -1);
                Point      p1    = new Point(0.9, 0, 0);
                Point      p2    = new Point(1.1, 0, 0);
                LightPoint light = new LightPoint(new Point(0, 0, -10), new Color(1, 1, 1));
                Color      c1    = Ops.Lighting(m, s, light, p1, eyev, normalv, false);
                Color      c2    = Ops.Lighting(m, s, light, p2, eyev, normalv, false);
                bool       foo1  = (c1.Equals(white));
                bool       foo2  = (c2.Equals(black));
                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            //public void PatternWithObjectTransformation()

            {
                Shape shape = new Sphere()
                {
                    Transform = MatrixOps.CreateScalingTransform(2, 2, 2)
                };
                Pattern pattern = new TestPattern {
                    Transform = MatrixOps.CreateTranslationTransform(0.5, 1, 1.5)
                };
                Color c    = pattern.PatternAtObject(shape, new Point(2.5, 3, 3.5));
                bool  foo1 = (c.Equals(new Color(0.75, 0.5, 0.25)));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }

            //public void GradientInterpolates()
            {
                Pattern pattern = new GradientPattern(black, white);
                bool    foo1    = (pattern.PatternAt(new Point(0, 0, 0)).Equals(black));
                bool    foo2    = (pattern.PatternAt(new Point(0.25, 0, 0)).Equals(new Color(0.25, 0.25, 0.25)));
                bool    foo3    = (pattern.PatternAt(new Point(0.5, 0, 0)).Equals(new Color(0.5, 0.5, 0.5)));
                bool    foo4    = (pattern.PatternAt(new Point(0.75, 0, 0)).Equals(new Color(0.75, 0.75, 0.75)));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            {
                Pattern pattern = new CheckedPattern(black, white);
                bool    foo1    = (pattern.PatternAt(new Point(0, 0, 0)).Equals(black));
                bool    foo2    = (pattern.PatternAt(new Point(0.99, 0, 0)).Equals(black));
                bool    foo3    = (pattern.PatternAt(new Point(1.01, 0, 0)).Equals(white));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }
            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }
예제 #8
0
파일: Program.cs 프로젝트: kemptm/RayTracer
        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Main entry-point for this application. </summary>
        ///
        /// <remarks>   Kemp, 1/18/2019. </remarks>
        ///
        /// <param name="args"> An array of command-line argument strings. </param>
        ///-------------------------------------------------------------------------------------------------

        static void Main(string[] args)
        {
            World defaultWorld = new World();

            defaultWorld.AddLight(new LightPoint(new Point(-10, 10, -10), new Color(1, 1, 1)));

            Sphere s1 = new Sphere();

            s1.Material          = new Material();
            s1.Material.Color    = new Color(0.8, 1.0, 0.6);
            s1.Material.Diffuse  = new Color(0.7, 0.7, 0.7);
            s1.Material.Specular = new Color(0.2, 0.2, 0.2);

            Sphere s2 = new Sphere();

            s2.Transform = MatrixOps.CreateScalingTransform(0.5, 0.5, 0.5);
            defaultWorld.AddObject(s1);
            defaultWorld.AddObject(s2);

            {
                //ComputingNormalOnTranslatedShape
                TestShape s = new TestShape();
                s.Transform = MatrixOps.CreateTranslationTransform(0, 1, 0);
                RayTracerLib.Vector n = s.NormalAt(new Point(0, 1.70711, -0.70711));
                bool foo = (n.Equals(new RayTracerLib.Vector(0, 0.70711, -0.70711)));

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }

            {
                World w = new World();
                w.AddLight(new LightPoint(new Point(-10, 10, -10), new Color(1, 1, 1)));

                Sphere s3 = new Sphere();
                s3.Material          = new Material();
                s3.Material.Color    = new Color(0.8, 1.0, 0.6);
                s3.Material.Diffuse  = new Color(0.7, 0.7, 0.7);
                s3.Material.Specular = new Color(0.2, 0.2, 0.2);
                w.AddObject(s3);

                Plane p = new Plane();
                p.Transform        = (Matrix)(MatrixOps.CreateTranslationTransform(0, 0, 2) * MatrixOps.CreateRotationXTransform(Math.PI / 2));
                p.Material.Pattern = new CheckedPattern(new Color(0, 0, 1), new Color(1, 0.9, 0.9));
                w.AddObject(p);

                Plane p1 = new Plane();
                p1.Transform        = MatrixOps.CreateTranslationTransform(1, 0, 0);
                p1.Material.Pattern = new GradientPattern(new Color(1, 0, 0), new Color(1, 0.9, 0.9));
                w.AddObject(p1);


                Ray r = new Ray(new Point(1, 1, -5), new RayTracerLib.Vector(0, -0.5, 0));
                List <Intersection> xs = p.Intersect(r);
                bool foo1, foo2, foo3;
                if (xs.Count > 0)
                {
                    foo1 = (xs.Count == 1);
                    foo2 = (xs[0].T >= 1);
                    foo3 = (xs[0].Obj.Equals(p));
                }

                Camera camera = new Camera(400, 200, Math.PI / 2);
                camera.Transform = MatrixOps.CreateViewTransform(new Point(3, 3, -5), new Point(0, 0, 0), new RayTracerLib.Vector(0, 1, 0));

                Canvas image = w.Render(camera);

                String ppm = image.ToPPM();

                System.IO.File.WriteAllText(@"ToPPM.ppm", ppm);

                Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~");
            }

            Console.Write("Press Enter to finish ... ");
            Console.Read();
        }