public void DrawTriangle(Vertex a, Vertex b, Vertex c)
        {
            a = SpaceToScreen(a);
            b = SpaceToScreen(b);
            c = SpaceToScreen(c);

            if (a.Coordinate.Y > b.Coordinate.Y)
            {
                Swap(ref a, ref b);
            }
            if (a.Coordinate.Y > c.Coordinate.Y)
            {
                Swap(ref a, ref c);
            }
            if (b.Coordinate.Y > c.Coordinate.Y)
            {
                Swap(ref b, ref c);
            }

            Vertex left  = new Vertex();
            Vertex right = new Vertex();
            Vertex point = new Vertex();

            for (double y = a.Coordinate.Y; y < c.Coordinate.Y; ++y)
            {
                if (y < 0 || y > (Height - 1))
                {
                    continue;
                }

                bool topHalf = y < b.Coordinate.Y;

                var a0 = a;
                var a1 = c;
                Interpolate(a0, a1, (y - a0.Coordinate.Y) / (a1.Coordinate.Y - a0.Coordinate.Y), ref left);

                var b0 = topHalf ? a : b;
                var b1 = topHalf ? b : c;
                Interpolate(b0, b1, (y - b0.Coordinate.Y) / (b1.Coordinate.Y - b0.Coordinate.Y), ref right);

                if (left.Coordinate.X > right.Coordinate.X)
                {
                    Swap(ref left, ref right);
                }

                for (double x = left.Coordinate.X; x < right.Coordinate.X; ++x)
                {
                    if (x < 0 || x > (Width - 1))
                    {
                        continue;
                    }

                    Interpolate(left, right, (x - left.Coordinate.X) / (right.Coordinate.X - left.Coordinate.X), ref point);

                    if (point.Coordinate.Z > 1 || point.Coordinate.Z < -1)
                    {
                        continue;
                    }

                    if (point.Coordinate.Z < ZBuffer[(int)x, (int)y])
                    {
                        ZBuffer[(int)x, (int)y] = point.Coordinate.Z;
                        ColorBuffer.SetPixel((int)x, (int)y, point.Color);
                    }
                }
            }
        }
 private Vertex SpaceToScreen(Vertex vertex)
 {
     return(new Vertex(SpaceToScreenCoordinate(vertex.Coordinate), vertex.Normal, vertex.Color));
 }
 private void Interpolate(Vertex a, Vertex b, double f, ref Vertex v)
 {
     v.Coordinate = Interpolate(a.Coordinate, b.Coordinate, f);
     v.Normal     = Interpolate(a.Normal, b.Normal, f);
     v.Color      = Interpolate(a.Color, b.Color, f);
 }