Beispiel #1
0
        public override Vector normal(XYZPoint p)
        {
            Vector v1 = new Vector(points[0], points[1]);
            Vector v2 = new Vector(points[0], points[2]);

            return(v1[v2]);
        }
Beispiel #2
0
        public static Polyhedron CreateHexahedron(XYZPoint a, XYZPoint b, XYZPoint q)
        {
            XYZPoint[] cd      = GetVertecesForSquare(a, b, q);
            XYZPoint   c       = cd[0];
            XYZPoint   d       = cd[1];
            Vector     m       = new Vector(a, b);
            Vector     n       = new Vector(a, c);
            double     sideLen = m.Norm();
            Vector     h       = m[n].Normalize() * sideLen;
            XYZPoint   a1      = new XYZPoint(a.X + h.X, a.Y + h.Y, a.Z + h.Z);
            XYZPoint   b1      = new XYZPoint(b.X + h.X, b.Y + h.Y, b.Z + h.Z);
            XYZPoint   c1      = new XYZPoint(c.X + h.X, c.Y + h.Y, c.Z + h.Z);
            XYZPoint   d1      = new XYZPoint(d.X + h.X, d.Y + h.Y, d.Z + h.Z);

            Polyhedron Hexahedron = new Polyhedron();

            Hexahedron.verges    = new Verge[6];
            Hexahedron.verges[0] = Verge.CreateSquare(a, b, c, d);
            Hexahedron.verges[1] = Verge.CreateSquare(a, b, b1, a1);
            Hexahedron.verges[2] = Verge.CreateSquare(b, c, c1, b1);
            Hexahedron.verges[3] = Verge.CreateSquare(c, d, d1, c1);
            Hexahedron.verges[4] = Verge.CreateSquare(a, d, d1, a1);
            Hexahedron.verges[5] = Verge.CreateSquare(a1, b1, c1, d1);

            double cx = (a.X + c1.X) / 2;
            double cy = (a.Y + c1.Y) / 2;
            double cz = (a.Z + c1.Z) / 2;

            Hexahedron.center = new XYZPoint(cx, cy, cz);

            return(Hexahedron);
        }
Beispiel #3
0
        private List <XYZPoint> find_rays()
        {
            var             corners = make_grid_corners(pictureBox1.Width * Math.Sqrt(3) / 2); // было 100
            List <XYZPoint> points  = new List <XYZPoint>();
            var             w       = pictureBox1.Width;
            var             h       = pictureBox1.Height;

            var step_h_x = (corners[2].X - corners[0].X) / h;
            var step_h_y = (corners[2].Y - corners[0].Y) / h;
            var step_h_z = (corners[2].Z - corners[0].Z) / h;

            var step_w_x = (corners[1].X - corners[0].X) / w;
            var step_w_y = (corners[1].Y - corners[0].Y) / w;
            var step_w_z = (corners[1].Z - corners[0].Z) / w;

            for (int i = 0; i < h; ++i)
            {
                var p = new XYZPoint(
                    corners[0].X + step_h_x * i,
                    corners[0].Y + step_h_y * i,
                    corners[0].Z + step_h_z * i);
                for (int j = 0; j < w; ++j)
                {
                    points.Add(new XYZPoint(
                                   p.X + step_w_x * j,
                                   p.Y + step_w_y * j,
                                   p.Z + step_w_z * j));
                }
            }

            return(points);
        }
Beispiel #4
0
 public XYZPoint[] GetPoints()
 {
     XYZPoint[] res = new XYZPoint[edges.Length];
     for (int i = 0; i < res.Length; ++i)
     {
         res[i] = edges[i].First;
     }
     return(res);
 }
Beispiel #5
0
        private double triangle_square(XYZPoint A, XYZPoint B, XYZPoint C)
        {
            double a = new Vector(B, C).Norm();
            double b = new Vector(A, C).Norm();
            double c = new Vector(A, B).Norm();
            double p = (a + b + c) / 2;

            return(Math.Sqrt(p * (p - a) * (p - b) * (p - c)));
        }
Beispiel #6
0
 public Polyhedron(Verge[] _verges, XYZPoint _center)
 {
     verges = new Verge[_verges.Length];
     for (int i = 0; i < verges.Length; ++i)
     {
         verges[i] = _verges[i].Clone() as Verge;
     }
     center = _center.Clone() as XYZPoint;
 }
Beispiel #7
0
        public static Verge CreateSquare(XYZPoint a, XYZPoint b, XYZPoint c, XYZPoint d)
        {
            Verge Square = new Verge();

            Square.edges = new Edge[4];

            Square.edges[0] = new Edge(a, b);
            Square.edges[1] = new Edge(b, c);
            Square.edges[2] = new Edge(c, d);
            Square.edges[3] = new Edge(d, a);

            return(Square);
        }
Beispiel #8
0
        public Wall(XYZPoint p1, XYZPoint p2, XYZPoint p3, XYZPoint p4)
        {
            Vector v1 = new Vector(p1, p2);
            Vector v2 = new Vector(p1, p3);
            Vector n  = v1[v2];
            double d  = -(n.X * p1.X + n.Y * p1.Y + n.Z * p1.Z);

            points    = new XYZPoint[4];
            points[0] = p1;
            points[1] = p2;
            points[2] = p3;
            points[3] = p4;
            square    = triangle_square(p1, p2, p3) + triangle_square(p1, p3, p4);
        }
Beispiel #9
0
        public override bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t)
        {
            Vector d = new Vector(
                ray_pos.X - Camera_pos.X,
                ray_pos.Y - Camera_pos.Y,
                ray_pos.Z - Camera_pos.Z);
            Vector c = new Vector(
                Camera_pos.X - this.C.X,
                Camera_pos.Y - this.C.Y,
                Camera_pos.Z - this.C.Z);

            double k1 = d * d,
                   k2 = 2 * (c * d),
                   k3 = (c * c) - this.R * this.R;
            double D  = k2 * k2 - 4 * k1 * k3;

            if (D < 0)
            {
                return(false);
            }

            double x1 = (-k2 + Math.Sqrt(D)) / (2 * k1);
            double x2 = (-k2 - Math.Sqrt(D)) / (2 * k1);
            double x  = 0;

            if (x1 < eps && x2 < eps)
            {
                return(false);
            }
            else if (x1 < eps)
            {
                x = x2;
            }
            else if (x2 < eps)
            {
                x = x1;
            }
            else
            {
                x = x1 < x2 ? x1 : x2;
            }

            t = new XYZPoint(
                Camera_pos.X + d.X * x,
                Camera_pos.Y + d.Y * x,
                Camera_pos.Z + d.Z * x);
            return(true);
        }
Beispiel #10
0
        private static XYZPoint[] GetVertecesForSquare(XYZPoint a, XYZPoint b, XYZPoint q)
        {
            Vector m       = new Vector(a, b);
            Vector n       = new Vector(a, q);
            double sideLen = m.Norm();

            double   coeff = (m * n) / (m * m);
            Vector   h     = (n - (coeff * m)).Normalize() * sideLen;
            Vector   r     = m + h;
            XYZPoint c     = new XYZPoint(a.X + r.X, a.Y + r.Y, a.Z + r.Z);
            XYZPoint d     = new XYZPoint(a.X + h.X, a.Y + h.Y, a.Z + h.Z);

            return(new XYZPoint[2] {
                c, d
            });
        }
Beispiel #11
0
        private void DrawButton_Click(Object sender, EventArgs e)
        {
            Init();

            var points = find_rays();

            var Camera_pos = new XYZPoint(2, 11, 2);

            g.Clear(ambient);
            for (int i = 0; i < pictureBox1.Height; i += 1)
            {
                for (int j = 0; j < pictureBox1.Width; j += 1)
                {
                    var clr = ray_step(Camera_pos, points[i * pictureBox1.Width + j], 1);
                    g.FillRectangle(new SolidBrush(clr), j, i, 1, 1);
                }
            }
        }
Beispiel #12
0
        private List <XYZPoint> make_grid_corners(double dist)
        {
            var    w      = pictureBox1.Width / 2;
            var    h      = pictureBox1.Height / 2;
            Camera Camera = CreateCamera();

            Vector   view = Camera.View * dist;
            XYZPoint m0   = new XYZPoint(
                Camera.Pos.X + view.X,
                Camera.Pos.Y + view.Y,
                Camera.Pos.Z + view.Z);

            Vector   hor  = Camera.Hor * w;
            Vector   vert = Camera.Vert * h;
            XYZPoint p1   = new XYZPoint(
                m0.X - hor.X - vert.X,
                m0.Y - hor.Y - vert.Y,
                m0.Z - hor.Z - vert.Z);
            XYZPoint p2 = new XYZPoint(
                m0.X + hor.X - vert.X,
                m0.Y + hor.Y - vert.Y,
                m0.Z + hor.Z - vert.Z);
            XYZPoint p3 = new XYZPoint(
                m0.X - hor.X + vert.X,
                m0.Y - hor.Y + vert.Y,
                m0.Z - hor.Z + vert.Z);
            XYZPoint p4 = new XYZPoint(
                m0.X + hor.X + vert.X,
                m0.Y + hor.Y + vert.Y,
                m0.Z + hor.Z + vert.Z);

            List <XYZPoint> res = new List <XYZPoint>();

            res.Add(p1);
            res.Add(p2);
            res.Add(p3);
            res.Add(p4);
            return(res);
        }
Beispiel #13
0
        public Sphere(Polyhedron ph)
        {
            var p    = ph.Verges[0].Edges[0].First;
            var dist = new Vector(ph.Center, p).Norm();

            foreach (var f in ph.Verges)
            {
                foreach (var e in f.Edges)
                {
                    var pp    = e.First;
                    var ddist = new Vector(ph.Center, pp).Norm();
                    if (ddist > dist)
                    {
                        dist = ddist;
                        p    = pp;
                    }
                }
            }

            this.center = ph.Center;
            this.radius = dist;
        }
Beispiel #14
0
        public override bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t)
        {
            Vector n = this.normal(null);
            double d = -(n.X * points[0].X + n.Y * points[0].Y + n.Z * points[0].Z);

            Vector v = new Vector(Camera_pos, ray_pos);
            Vector u = new Vector(Camera_pos);

            double denum = n * v;

            if (Math.Abs(denum) < eps)
            {
                return(false);
            }
            double num = n * u + d;
            double tp  = -num / denum;

            if (tp < eps)
            {
                return(false);
            }
            t = new XYZPoint(
                v.X * tp + u.X,
                v.Y * tp + u.Y,
                v.Z * tp + u.Z);
            double square = 0;

            for (int i = 0; i < 4; ++i)
            {
                square += triangle_square(points[i], points[(i + 1) % 4], t);
            }
            if (Math.Abs(this.square - square) > eps)
            {
                return(false);
            }

            return(true);
        }
Beispiel #15
0
        public override Vector normal(XYZPoint p)
        {
            foreach (var face in ph.Verges)
            {
                double square = 0;
                int    cnt    = face.Edges.Count();
                for (int i = 0; i < cnt; ++i)
                {
                    square += triangle_square(face.Edges[i].First, face.Edges[(i + 1) % cnt].First, p);
                }
                if (Math.Abs(squares[face] - square) > eps)
                {
                    continue;
                }

                var    p1 = face.Edges[0].First;
                var    p2 = face.Edges[1].First;
                var    p3 = face.Edges[2].First;
                Vector v1 = new Vector(p1, p2);
                Vector v2 = new Vector(p1, p3);
                return(v1[v2]);
            }
            return(new Vector());
        }
Beispiel #16
0
 public Edge(XYZPoint a, XYZPoint b)
 {
     this.a = new XYZPoint(a);
     this.b = new XYZPoint(b);
 }
Beispiel #17
0
 public Sphere(XYZPoint c, double r)
 {
     this.center = c;
     this.radius = r;
 }
Beispiel #18
0
 virtual public bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t)
 {
     return(true);
 }
Beispiel #19
0
 public XYZPoint(XYZPoint a)
 {
     x = a.x;
     y = a.y;
     z = a.z;
 }
Beispiel #20
0
 public void Copy(XYZPoint a)
 {
     x = a.x;
     y = a.y;
     z = a.z;
 }
Beispiel #21
0
        private Color ray_step(XYZPoint start, XYZPoint p, double intense)
        {
            if (intense < 0.01)
            {
                return(Color.Black);
            }

            double   dist  = double.MaxValue;
            Model    obj   = null;
            XYZPoint cross = new XYZPoint();

            foreach (var o in Models)
            {
                XYZPoint t = new XYZPoint();
                if (o.find_cross(start, p, ref t))
                {
                    double d1 = new Vector(start, t).Norm();
                    if (d1 < dist)
                    {
                        dist  = d1;
                        obj   = o;
                        cross = t;
                    }
                }
            }

            if (obj == null)
            {
                return(ambient);
            }

            // диффузное освещение
            double   ldiff = 0;
            XYZPoint tt    = new XYZPoint();

            foreach (var l in lights)
            {
                bool   flag        = false;
                double trans_coeff = 1;
                foreach (var o in Models)
                {
                    if (o.find_cross(cross, l, ref tt) && new Vector(tt, cross).Norm() < new Vector(l, cross).Norm())
                    {
                        if (trans[o] > 0)
                        {
                            trans_coeff *= trans[o];
                        }
                        else
                        {
                            flag = true;
                            break;
                        }
                    }
                }
                if (flag)
                {
                    continue;
                }

                double kd = diffuse[obj];
                double l0 = lights_power[l];
                Vector N  = obj.normal(cross);
                Vector L  = new Vector(cross, l);
                if (N * L < 0)
                {
                    N = -N;
                }
                double cos = (N * L) / N.Norm() / L.Norm();
                ldiff += kd * cos * l0 * trans_coeff;
            }

            Color clr_diff = light_color(colors[obj], (ldiff + amb_light) * intense);

            // отражение
            Color clr_refl = Color.Black;

            if (reflect[obj] > 0)
            {
                Vector l = new Vector(start, p);
                l = l.Normalize();
                Vector n = obj.normal(cross);
                n = n.Normalize();
                if (n * l > 0)
                {
                    n = -n;
                }
                Vector   r     = l - 2 * n * (n * l);
                XYZPoint p_new = new XYZPoint(
                    cross.X + r.X,
                    cross.Y + r.Y,
                    cross.Z + r.Z);
                clr_refl = ray_step(cross, p_new, intense * reflect[obj]);
            }

            //преломление
            Color clr_trans = Color.Black;

            if (trans[obj] > 0)
            {
                Vector l = new Vector(start, p);
                l = l.Normalize();
                Vector n = obj.normal(cross);
                n = n.Normalize();
                if (n * l > 0)
                {
                    n = -n;
                }
                double   coef  = 1 / refract[obj];
                double   cos   = Math.Sqrt(1 - coef * coef * (1 - (n * l) * (n * l)));
                Vector   t     = coef * l - (cos + coef * (n * l)) * n;
                XYZPoint p_new = new XYZPoint(
                    cross.X + t.X,
                    cross.Y + t.Y,
                    cross.Z + t.Z);

                for (int i = 0; i < 10; ++i)
                {
                    if (!obj.find_cross(cross, p_new, ref tt))
                    {
                        return(clr_diff);
                    }

                    l = new Vector(cross, p_new);
                    l = l.Normalize();
                    n = obj.normal(tt);
                    n.Normalize();
                    if (n * l > 0)
                    {
                        n = -n;
                    }
                    coef = refract[obj];
                    cos  = 1 - coef * coef * (1 - (n * l) * (n * l));
                    if (cos < 0)
                    {
                        if (i == 9)
                        {
                            cross = tt;
                            p_new = new XYZPoint(
                                cross.X + l.X,
                                cross.Y + l.Y,
                                cross.Z + l.Z);
                            break;
                        }
                        Vector r = l - 2 * n * (n * l);
                        cross = tt;
                        p_new = new XYZPoint(
                            cross.X + r.X,
                            cross.Y + r.Y,
                            cross.Z + r.Z);
                        continue;
                    }
                    cos   = Math.Sqrt(cos);
                    t     = coef * l - (cos + coef * (n * l)) * n;
                    p_new = new XYZPoint(
                        tt.X + t.X,
                        tt.Y + t.Y,
                        tt.Z + t.Z);
                    break;
                }

                clr_trans = ray_step(tt, p_new, intense * trans[obj]);
            }

            return(add_colors(clr_diff, clr_refl, clr_trans, reflect[obj] > 0, trans[obj] > 0));
        }
Beispiel #22
0
 public override Vector normal(XYZPoint p)
 {
     return(new Vector(this.C, p));
 }
Beispiel #23
0
 public Vector(XYZPoint a, XYZPoint b)
 {
     this.x = b.X - a.X;
     this.y = b.Y - a.Y;
     this.z = b.Z - a.Z;
 }
Beispiel #24
0
 public Vector(XYZPoint a)
 {
     this.x = a.X;
     this.y = a.Y;
     this.z = a.Z;
 }
Beispiel #25
0
        public override bool find_cross(XYZPoint Camera_pos, XYZPoint ray_pos, ref XYZPoint t)
        {
            if (!outside_sphere.find_cross(Camera_pos, ray_pos, ref t))
            {
                return(false);
            }

            double   dist = double.MaxValue;
            XYZPoint res  = new XYZPoint();
            bool     flag = false;

            foreach (var face in ph.Verges)
            {
                var    p1 = face.Edges[0].First;
                var    p2 = face.Edges[1].First;
                var    p3 = face.Edges[2].First;
                Vector v1 = new Vector(p1, p2);
                Vector v2 = new Vector(p1, p3);
                Vector n  = v1[v2];
                double d  = -(n.X * p1.X + n.Y * p1.Y + n.Z * p1.Z);

                Vector v = new Vector(Camera_pos, ray_pos);
                Vector u = new Vector(Camera_pos);

                double denum = n * v;
                if (Math.Abs(denum) < eps)
                {
                    continue;
                }
                double num = n * u + d;
                double tp  = -num / denum;
                if (tp < eps)
                {
                    continue;
                }
                t = new XYZPoint(
                    v.X * tp + u.X,
                    v.Y * tp + u.Y,
                    v.Z * tp + u.Z);

                double square = 0;
                int    cnt    = face.Edges.Count();
                for (int i = 0; i < cnt; ++i)
                {
                    square += triangle_square(face.Edges[i].First, face.Edges[(i + 1) % cnt].First, t);
                }
                if (Math.Abs(squares[face] - square) > eps)
                {
                    continue;
                }
                var dist_t = new Vector(Camera_pos, t).Norm();
                if (dist_t < dist)
                {
                    res  = t.Clone() as XYZPoint;
                    dist = dist_t;
                    flag = true;
                }
            }

            t = res.Clone() as XYZPoint;
            return(flag);
        }
Beispiel #26
0
 virtual public Vector normal(XYZPoint p)
 {
     return(new Vector());
 }