예제 #1
0
 public Sphere(Point3D p, float r)
 {
     points.Add(p);
     radius = r;
 }
예제 #2
0
        public Point3D color_light;       // цвет источника света

        public Light(Point3D p, Point3D c)
        {
            point_light = new Point3D(p);
            color_light = new Point3D(c);
        }
예제 #3
0
 /// <summary>
 /// rotate figure line
 /// </summary>
 /// <param name="ang">angle in degrees</param>
 /// <param name="p1">line start</param>
 /// <param name="p2">line end</param>
 public void line_rotate(float ang, Point3D p1, Point3D p2)
 {
     ang = ang * (float)Math.PI / 180;
     line_rotate_rad(ang, p1, p2);
 }
예제 #4
0
        ///
        /// ----------------------------- STATIC BACKEND FOR TRANSFROMS --------------------------------
        ///

        private static float[,] rotate_around_line(float[,] transform_matrix, Point3D start, Point3D dir, float angle)
        {
            float cos_angle = (float)Math.Cos(angle);
            float sin_angle = (float)Math.Sin(angle);
            float val00     = dir.x * dir.x + cos_angle * (1 - dir.x * dir.x);
            float val01     = dir.x * (1 - cos_angle) * dir.y + dir.z * sin_angle;
            float val02     = dir.x * (1 - cos_angle) * dir.z - dir.y * sin_angle;
            float val10     = dir.x * (1 - cos_angle) * dir.y - dir.z * sin_angle;
            float val11     = dir.y * dir.y + cos_angle * (1 - dir.y * dir.y);
            float val12     = dir.y * (1 - cos_angle) * dir.z + dir.x * sin_angle;
            float val20     = dir.x * (1 - cos_angle) * dir.z + dir.y * sin_angle;
            float val21     = dir.y * (1 - cos_angle) * dir.z - dir.x * sin_angle;
            float val22     = dir.z * dir.z + cos_angle * (1 - dir.z * dir.z);

            float[,] rotateMatrix = new float[, ] {
                { val00, val01, val02, 0 }, { val10, val11, val12, 0 }, { val20, val21, val22, 0 }, { 0, 0, 0, 1 }
            };
            return(apply_offset(multiply_matrix(apply_offset(transform_matrix, -start.x, -start.y, -start.z), rotateMatrix), start.x, start.y, start.z));
        }
예제 #5
0
 public static float scalar(Point3D p1, Point3D p2)
 {
     return(p1.x * p2.x + p1.y * p2.y + p1.z * p2.z);
 }
예제 #6
0
 public void CalculateSideNormal()
 {
     Normal = norm(this);
 }
예제 #7
0
        public void build_scene()
        {
            Figure room = Figure.get_Hexahedron(10);

            up_left    = room.sides[0].get_point(0);
            up_right   = room.sides[0].get_point(1);
            down_right = room.sides[0].get_point(2);
            down_left  = room.sides[0].get_point(3);

            Point3D normal = Side.norm(room.sides[0]);                            // нормаль стороны комнаты
            Point3D center = (up_left + up_right + down_left + down_right) / 4;   // центр стороны комнаты

            focus = center + normal * 10;

            room.set_pen(new Pen(Color.Gray));
            room.sides[0].drawing_pen = new Pen(Color.Green);
            room.sides[1].drawing_pen = new Pen(Color.Gold);
            room.sides[2].drawing_pen = new Pen(Color.DeepPink);
            room.sides[3].drawing_pen = new Pen(Color.BlueViolet);
            room.figure_material      = new Material(0f, 0, 0.05f, 0.7f);

            Light l1 = new Light(new Point3D(0f, 2f, 4.9f), new Point3D(1f, 1f, 1f));
            Light l2 = new Light(new Point3D(-4.9f, -4.9f, 4.9f), new Point3D(1f, 1f, 1f));

            lights.Add(l1);
            lights.Add(l2);

            Sphere s1 = new Sphere(new Point3D(-2.5f, 1.7f, -3.7f), 1.4f);

            s1.set_pen(new Pen(Color.White));
            s1.figure_material = new Material(0.05f, 0.9f, 0f, 0f, 1.05f);

            Sphere s2 = new Sphere(new Point3D(-2.5f, -2, 2.5f), 2f);

            s2.set_pen(new Pen(Color.White));
            s2.figure_material = new Material(0.9f, 0f, 0f, 0.1f, 1f);

            Figure cube1 = Figure.get_Hexahedron(2.8f);

            cube1.offset(-0.5f, -1, -3.9f);
            cube1.rotate_around(55, "CZ");
            cube1.set_pen(new Pen(Color.Aqua));
            cube1.figure_material = new Material(0f, 0f, 0.1f, 0.7f, 1.5f);

            Figure cube2 = Figure.get_Hexahedron(1.5f);

            cube2.offset(-0.5f, -0.9f, -1.7f);
            cube2.rotate_around(120, "CZ");
            cube2.set_pen(new Pen(Color.White));
            cube2.figure_material = new Material(0.9f, 0f, 0f, 0.1f, 1.2f);

            Figure cube3 = Figure.get_Hexahedron(2f);

            cube3.offset(2.7f, 2.5f, -3.95f);
            cube3.rotate_around(-10, "CZ");
            cube3.set_pen(new Pen(Color.Red));
            cube3.figure_material = new Material(0, 0.7f, 0.1f, 0.5f, 1f);

            scene.Add(room);
            scene.Add(cube1);
            scene.Add(cube2);
            scene.Add(cube3);
            scene.Add(s1);
            scene.Add(s2);
        }
예제 #8
0
        // отражение
        public Ray reflect(Point3D hit_point, Point3D normal)
        {
            Point3D reflect_dir = direction - 2 * normal * Point3D.scalar(direction, normal);

            return(new Ray(hit_point, hit_point + reflect_dir));
        }
예제 #9
0
 public Ray(Ray r)
 {
     start     = r.start;
     direction = r.direction;
 }
예제 #10
0
 public Ray(Point3D st, Point3D end)
 {
     start     = new Point3D(st);
     direction = Point3D.norm(end - st);
 }
예제 #11
0
        public Point3D RayTrace(Ray r, int iter, float env)
        {
            if (iter <= 0)
            {
                return(new Point3D(0, 0, 0));
            }

            float    t                     = 0; // позиция точки пересечения луча с фигурой на луче
            Point3D  normal                = null;
            Material m                     = new Material();
            Point3D  res_color             = new Point3D(0, 0, 0);
            bool     refract_out_of_figure = false;

            foreach (Figure fig in scene)
            {
                if (fig.figure_intersection(r, out float intersect, out Point3D n))
                {
                    if (intersect < t || t == 0)     // нужна ближайшая фигура к точке наблюдения
                    {
                        t      = intersect;
                        normal = n;
                        m      = new Material(fig.figure_material);
                    }
                }
            }

            if (t == 0)
            {
                return(new Point3D(0, 0, 0));
            }

            if (Point3D.scalar(r.direction, normal) > 0)
            {
                normal *= -1;
                refract_out_of_figure = true;
            }

            Point3D hit_point = r.start + r.direction * t;

            foreach (Light l in lights)
            {
                Point3D amb = l.color_light * m.ambient;
                amb.x      = (amb.x * m.clr.x);
                amb.y      = (amb.y * m.clr.y);
                amb.z      = (amb.z * m.clr.z);
                res_color += amb;

                // диффузное освещение
                if (is_visible(l.point_light, hit_point))
                {
                    res_color += l.shade(hit_point, normal, m.clr, m.diffuse);
                }
            }

            if (m.reflection > 0)
            {
                Ray reflected_ray = r.reflect(hit_point, normal);
                res_color += m.reflection * RayTrace(reflected_ray, iter - 1, env);
            }

            if (m.refraction > 0)
            {
                float eta;
                if (refract_out_of_figure)
                {
                    eta = m.environment;
                }
                else
                {
                    eta = 1 / m.environment;
                }

                Ray refracted_ray = r.refract(hit_point, normal, eta);
                if (refracted_ray != null)
                {
                    res_color += m.refraction * RayTrace(refracted_ray, iter - 1, m.environment);
                }
            }

            return(res_color);
        }