Exemplo n.º 1
0
        private static Mesh CreateDodecahedron(double r)
        {
            var vertices = new MyMatrix <double>(new double[, ] {
                { 0.469, 0.469, 0.469, 1 },
                { 0.290, 0.000, 0.759, 1 },
                { -0.759, -0.290, 0.000, 1 },
                { 0.759, 0.290, 0.000, 1 },
                { -0.469, 0.469, -0.469, 1 },
                { 0.000, -0.759, -0.290, 1 },
                { -0.759, 0.290, 0.000, 1 },
                { 0.469, -0.469, 0.469, 1 },
                { -0.469, 0.469, 0.469, 1 },
                { -0.469, -0.469, 0.469, 1 },
                { 0.469, -0.469, -0.469, 1 },
                { 0.290, 0.000, -0.759, 1 },
                { -0.469, -0.469, -0.469, 1 },
                { 0.000, -0.759, 0.290, 1 },
                { 0.000, 0.759, -0.290, 1 },
                { -0.290, 0.000, 0.759, 1 },
                { 0.759, -0.290, 0.000, 1 },
                { -0.290, 0.000, -0.759, 1 },
                { 0.469, 0.469, -0.469, 1 },
                { 0.000, 0.759, 0.290, 1 }
            });

            var incident = MyMatrix <double> .Incident(4, r);

            vertices = vertices * incident;

            for (var i = 0; i < vertices.Height; ++i)
            {
                vertices[i, 3] = 1;
            }

            var faces = new MyMatrix <int>(new int[, ]
            {
                { 9, 13, 7, 1, 15 },
                { 6, 4, 14, 19, 8 },
                { 12, 5, 13, 9, 2 },
                { 6, 2, 12, 17, 4 },
                { 16, 10, 11, 18, 3 },
                { 19, 8, 15, 1, 0 },
                { 16, 7, 1, 0, 3 },
                { 5, 12, 17, 11, 10 },
                { 18, 14, 4, 17, 11 },
                { 16, 10, 5, 13, 7 },
                { 2, 6, 8, 15, 9 },
                { 19, 0, 3, 18, 14 }
            });

            return(new Mesh(faces, vertices));
        }
Exemplo n.º 2
0
        private MyMatrix <int> CalculateScreenCoordinates(MyMatrix <double> projectedVertices)
        {
            var result     = new MyMatrix <int>(projectedVertices.Height, 2);
            int halfWidth  = m_screenWidth / 2;
            int halfHeight = m_screenHeight / 2;

            for (var i = 0; i < result.Height; ++i)
            {
                result[i, 0] = (int)(halfWidth * projectedVertices[i, 0] + halfWidth);
                result[i, 1] = (int)(-halfHeight * projectedVertices[i, 1] + halfHeight);
            }
            return(result);
        }
Exemplo n.º 3
0
        private static Mesh CreateGrarlic(double r)
        {
            var horizontalSegments = 20;
            var verticalSegments   = 16;
            var vertices           = new MyMatrix <double>(horizontalSegments * (verticalSegments + 1), 4);

            for (var i = 0; i <= verticalSegments; ++i)
            {
                var theta = -Math.PI / 2 + Math.PI / verticalSegments * i;
                var y     = r * Math.Sin(theta);
                if (theta > 0)
                {
                    var t = theta / (Math.PI / 2.0);
                    t = Math.Pow(t, 5);
                    t = r * t;
                }
                var projection = r * Math.Cos(theta);
                for (var j = 0; j < horizontalSegments; ++j)
                {
                    var fi         = 2 * Math.PI / horizontalSegments * j;
                    var multiplier = 1.0 + 0.5 * Math.Abs(Math.Sin(2 * fi));
                    var x          = projection * Math.Cos(fi) * multiplier;
                    var z          = projection * Math.Sin(fi) * multiplier;
                    vertices[i * horizontalSegments + j, 0] = x;
                    vertices[i * horizontalSegments + j, 1] = y + (theta > 0 ? r * Math.Pow(theta / (Math.PI / 2.0), 5) : 0.0);
                    vertices[i * horizontalSegments + j, 2] = z;
                    vertices[i * horizontalSegments + j, 3] = 1;
                }
            }

            var faces = new MyMatrix <int>(2 * horizontalSegments * verticalSegments, 3);

            for (var i = 0; i < verticalSegments; ++i)
            {
                for (var j = 0; j < horizontalSegments; ++j)
                {
                    var index = i * horizontalSegments + j;
                    faces[2 * index, 0] = index;
                    faces[2 * index, 1] = (index + 1) % horizontalSegments == 0 ? index - horizontalSegments + 1 : index + 1;
                    faces[2 * index, 2] = (index + 1) % horizontalSegments == 0 ? index + 1 : index + horizontalSegments + 1;

                    faces[2 * index + 1, 0] = index;
                    faces[2 * index + 1, 1] = (index + 1) % horizontalSegments == 0 ? index + 1 : index + horizontalSegments + 1;
                    faces[2 * index + 1, 2] = index + horizontalSegments;
                }
            }

            return(new Mesh(faces, vertices));
        }
Exemplo n.º 4
0
        public static MyMatrix <double> Inverse(MyMatrix <double> matrix)
        {
            var array1d               = matrix.GetInternalStorage().Cast <double>().ToArray();
            var mathnetMatrix         = new DenseMatrix(matrix.Height, matrix.Width, array1d);
            var inversedMathnetMatrix = mathnetMatrix.Inverse();
            var result = new MyMatrix <double>(inversedMathnetMatrix.RowCount, inversedMathnetMatrix.ColumnCount);

            for (int i = 0; i < inversedMathnetMatrix.RowCount; ++i)
            {
                for (int j = 0; j < inversedMathnetMatrix.ColumnCount; ++j)
                {
                    result[i, j] = inversedMathnetMatrix[i, j];
                }
            }
            return(result);
        }
Exemplo n.º 5
0
        private static void CreateVerticesForFace(
            double xStart
            , double yStart
            , double zStart
            , double newLineXStep
            , double newLineYStep
            , double newLineZStep
            , double xStep
            , double yStep
            , double zStep
            , double radius
            , int subdivisions
            , int startIndex
            , MyMatrix <double> vertices)
        {
            vertices[startIndex, 0] = xStart;
            vertices[startIndex, 1] = yStart;
            vertices[startIndex, 2] = zStart;

            var numberOfLines = (int)Math.Pow(2, subdivisions) + 1;

            for (int lineNumber = 1, index = startIndex + 1; lineNumber < numberOfLines; ++lineNumber)
            {
                var firstVertexX           = xStart + newLineXStep * lineNumber;
                var firstVertexY           = yStart + newLineYStep * lineNumber;
                var firstVertexZ           = zStart + newLineZStep * lineNumber;
                var numberOfVerticesInLine = lineNumber + 1;
                for (int vertexNumberInLine = 0; vertexNumberInLine < numberOfVerticesInLine; ++vertexNumberInLine)
                {
                    var x = firstVertexX + xStep * vertexNumberInLine;
                    var y = firstVertexY + yStep * vertexNumberInLine;
                    var z = firstVertexZ + zStep * vertexNumberInLine;

                    var length = Utilities.Length(x, y, z, 0, 0, 0);
                    x *= radius / length;
                    y *= radius / length;
                    z *= radius / length;

                    vertices[index, 0] = x;
                    vertices[index, 1] = y;
                    vertices[index, 2] = z;
                    ++index;
                }
            }
        }
Exemplo n.º 6
0
        public MainWindow()
        {
            InitializeComponent();
            m_bitmap                  = new WriteableBitmap((int)image.Width, (int)image.Height, 96, 96, PixelFormats.Bgr32, null);
            image.Source              = m_bitmap;
            image.Stretch             = Stretch.None;
            image.HorizontalAlignment = HorizontalAlignment.Left;
            image.VerticalAlignment   = VerticalAlignment.Top;

            var vertices = new double[, ]
            {
                { 0, 0, 0, 1 },
                { 1, 0, 0, 1 },
                { 0.5, -0.2, 1, 1 },
                { 0.5, 1, 0.5, 1 }
            };

            var faces = new int[, ]
            {
                { 1, 0, 3 },
                { 2, 1, 3 },
                { 0, 2, 3 },
                { 2, 0, 1 }
            };

            var defaultObject = new MyObject("default", new Vector3D(0, 0, 0), new Vector3D(0, 0, 0), Default.SCALE, Shape.Tetrahedron);

            AddObject(defaultObject);
            objectsListBox.SelectedIndex = 0;
            var r           = -1.0 / 15.0;
            var perspective = new double[, ]
            {
                { 1, 0, 0, 0 },
                { 0, 1, 0, 0 },
                { 0, 0, 0, r },
                { 0, 0, 0, 1 }
            };
            var projection = new MyMatrix <double>(perspective);

            m_currentObject = GetCurrentObject();
            m_drawer        = new Drawer(projection, (int)m_bitmap.Width, (int)m_bitmap.Height);
            projectionComboBox.SelectedIndex = 0;
            Redraw();
        }
Exemplo n.º 7
0
        private static Mesh CreateSphere(double r)
        {
            var horizontalSegments = 14;
            var verticalSegments   = 14;
            var vertices           = new MyMatrix <double>(horizontalSegments * (verticalSegments + 1), 4);

            for (var i = 0; i <= verticalSegments; ++i)
            {
                var theta      = -Math.PI / 2 + Math.PI / verticalSegments * i;
                var y          = r * Math.Sin(theta);
                var projection = r * Math.Cos(theta);
                for (var j = 0; j < horizontalSegments; ++j)
                {
                    var fi = 2 * Math.PI / horizontalSegments * j;
                    var x  = projection * Math.Cos(fi);
                    var z  = projection * Math.Sin(fi);

                    vertices[i * horizontalSegments + j, 0] = x;
                    vertices[i * horizontalSegments + j, 1] = y;
                    vertices[i * horizontalSegments + j, 2] = z;
                    vertices[i * horizontalSegments + j, 3] = 1;
                }
            }

            var faces = new MyMatrix <int>(2 * horizontalSegments * verticalSegments, 3);

            for (var i = 0; i < verticalSegments; ++i)
            {
                for (var j = 0; j < horizontalSegments; ++j)
                {
                    var index = i * horizontalSegments + j;
                    faces[2 * index, 0] = index;
                    faces[2 * index, 1] = (index + 1) % horizontalSegments == 0 ? index - horizontalSegments + 1 : index + 1;
                    faces[2 * index, 2] = (index + 1) % horizontalSegments == 0 ? index + 1 : index + horizontalSegments + 1;

                    faces[2 * index + 1, 0] = index;
                    faces[2 * index + 1, 1] = (index + 1) % horizontalSegments == 0 ? index + 1 : index + horizontalSegments + 1;
                    faces[2 * index + 1, 2] = index + horizontalSegments;
                }
            }

            return(new Mesh(faces, vertices));
        }
Exemplo n.º 8
0
        private static void CreateSpherePart(
            MyMatrix <double> tethraederVertices
            , int fristVertexIndex
            , int secondVertexIndex
            , int thirdVertexIndex
            , int subdivisions
            , int startIndex
            , double radius
            , MyMatrix <double> vertices
            , List <Face> faces)
        {
            var numberOfSegments = (int)Math.Pow(2, subdivisions);

            var newLineXStep = (tethraederVertices[secondVertexIndex, 0] - tethraederVertices[fristVertexIndex, 0]) / numberOfSegments;
            var newLineYStep = (tethraederVertices[secondVertexIndex, 1] - tethraederVertices[fristVertexIndex, 1]) / numberOfSegments;
            var newLineZStep = (tethraederVertices[secondVertexIndex, 2] - tethraederVertices[fristVertexIndex, 2]) / numberOfSegments;

            var xStep = (tethraederVertices[thirdVertexIndex, 0] - tethraederVertices[secondVertexIndex, 0]) / numberOfSegments;
            var yStep = (tethraederVertices[thirdVertexIndex, 1] - tethraederVertices[secondVertexIndex, 1]) / numberOfSegments;
            var zStep = (tethraederVertices[thirdVertexIndex, 2] - tethraederVertices[secondVertexIndex, 2]) / numberOfSegments;

            CreateVerticesForFace(
                tethraederVertices[fristVertexIndex, 0]
                , tethraederVertices[fristVertexIndex, 1]
                , tethraederVertices[fristVertexIndex, 2]
                , newLineXStep
                , newLineYStep
                , newLineZStep
                , xStep
                , yStep
                , zStep
                , radius
                , subdivisions
                , startIndex
                , vertices);


            CreateFacesForFace(
                startIndex
                , subdivisions
                , vertices
                , faces);
        }
Exemplo n.º 9
0
        private static Mesh CreateModifiedTorus(double r, double torusRadius)
        {
            var verticalSegments   = 8;
            var horizontalSegments = 36;
            var vertices           = new MyMatrix <double>(2 * verticalSegments * (horizontalSegments + 1), 4);

            for (var i = 0; i <= horizontalSegments; ++i)
            {
                var fi = 4 * Math.PI / horizontalSegments * i;
                for (var j = 0; j < verticalSegments; ++j)
                {
                    var theta = 2 * Math.PI / verticalSegments * j;
                    var x     = (r + torusRadius * Math.Cos(theta)) * Math.Cos(fi);
                    var y     = (r + torusRadius * Math.Cos(theta)) * Math.Sin(fi);
                    var z     = torusRadius * Math.Sin(theta) + torusRadius * fi;

                    vertices[i * verticalSegments + j, 0] = x;
                    vertices[i * verticalSegments + j, 1] = y;
                    vertices[i * verticalSegments + j, 2] = z;
                    vertices[i * verticalSegments + j, 3] = 1;
                }
            }

            var faces = new MyMatrix <int>(4 * verticalSegments * (horizontalSegments + 1), 3);

            for (var i = 0; i < horizontalSegments; ++i)
            {
                for (var j = 0; j < verticalSegments; ++j)
                {
                    var index = i * verticalSegments + j;
                    faces[2 * index, 0] = index;
                    faces[2 * index, 1] = index + verticalSegments;
                    faces[2 * index, 2] = (index + 1) % verticalSegments == 0 ? (i + 1) * verticalSegments : index + verticalSegments + 1;

                    faces[2 * index + 1, 0] = index;
                    faces[2 * index + 1, 1] = (index + 1) % verticalSegments == 0 ? (i + 1) * verticalSegments : index + verticalSegments + 1;
                    faces[2 * index + 1, 2] = (index + 1) % verticalSegments == 0 ? i * verticalSegments : index + 1;
                }
            }

            return(new Mesh(faces, vertices));
        }
Exemplo n.º 10
0
        public static MyMatrix <T> operator *(MyMatrix <T> first, MyMatrix <T> second)
        {
            if (first.Width != second.Height)
            {
                throw new ArgumentException("Matrix multiplication: first matrix width must be equal to second matrix height");
            }
            var result = new MyMatrix <T>(first.m_matrix.GetLength(0), second.m_matrix.GetLength(1));

            for (var i = 0; i < first.Height; ++i)
            {
                for (var j = 0; j < second.Width; ++j)
                {
                    for (var k = 0; k < first.Width; ++k)
                    {
                        result[i, j] += (dynamic)first[i, k] * (dynamic)second[k, j]; // some cheats with dynamic
                    }
                }
            }
            return(result);
        }
Exemplo n.º 11
0
 public Mesh(MyMatrix <int> faces, MyMatrix <double> vertices)
 {
     CheckNullFacesOrVertices(faces, vertices);
     if (faces.Height <= 0 || faces.Width < 3)
     {
         throw new ArgumentException(
                   "Wrong faces matrix size, height = " + faces.Height +
                   ", width = " + faces.Width
                   );
     }
     CheckVerticesShape(vertices);
     for (int i = 0; i < faces.Height; ++i)
     {
         var faceBuilder = new FaceBuilder();
         for (var j = 0; j < faces.Width; ++j)
         {
             faceBuilder.Add(faces[i, j]);
         }
         m_faces.Add(faceBuilder.Build());
     }
     m_vertices = vertices;
 }
Exemplo n.º 12
0
        private static Mesh CreateSphereWithoutPole(double r, int subdivisions)
        {
            var vertices = new MyMatrix <double>(4, 4);
            var a        = 4 * r / Math.Sqrt(6);
            var c        = (a / 2) / Math.Cos(Utilities.ToRadians(30));

            for (var i = 0; i < 3; ++i)
            {
                vertices[i, 0] = c * (Math.Cos(Utilities.ToRadians(150 + i * 120)));
                vertices[i, 1] = -Math.Sqrt(r * r - c * c);
                vertices[i, 2] = c * (Math.Sin(Utilities.ToRadians(-30 + i * 120)));
            }
            vertices[3, 0] = 0;
            vertices[3, 1] = r;
            vertices[3, 2] = 0;
            for (var i = 0; i < vertices.Height; ++i)
            {
                vertices[i, 3] = 1;
            }

            var sphereVertices = new MyMatrix <double>(4 * ((int)Math.Pow(2, subdivisions) + 1) * ((int)Math.Pow(2, subdivisions) + 2), 4);
            var faces          = new List <Face>();

            var numberOfSegments       = (int)Math.Pow(2, subdivisions);
            var numberOfVerticesInFace = ((int)Math.Pow(2, subdivisions) + 1) * ((int)Math.Pow(2, subdivisions) + 2) / 2;

            CreateSpherePart(vertices, 3, 0, 2, subdivisions, 0, r, sphereVertices, faces);
            CreateSpherePart(vertices, 3, 1, 0, subdivisions, numberOfVerticesInFace, r, sphereVertices, faces);
            CreateSpherePart(vertices, 3, 2, 1, subdivisions, 2 * numberOfVerticesInFace, r, sphereVertices, faces);
            CreateSpherePart(vertices, 2, 1, 0, subdivisions, 3 * numberOfVerticesInFace, r, sphereVertices, faces);

            for (int i = 0; i < sphereVertices.Height; ++i)
            {
                sphereVertices[i, 3] = 1;
            }

            return(new Mesh(faces, sphereVertices));
        }
Exemplo n.º 13
0
        private static Mesh CreateOctahedron(double r)
        {
            var vertices = new MyMatrix <double>(6, 4);
            var a        = 6 * r / Math.Sqrt(6);

            vertices[0, 0] = vertices[1, 0] = -a / 2;
            vertices[2, 0] = vertices[3, 0] = a / 2;
            vertices[4, 0] = vertices[5, 0] = 0;

            vertices[0, 1] = vertices[1, 1] = vertices[2, 1] = vertices[3, 1] = 0;
            vertices[4, 1] = r;
            vertices[5, 1] = -r;

            vertices[1, 2] = vertices[2, 2] = -a / 2;
            vertices[0, 2] = vertices[3, 2] = a / 2;
            vertices[4, 2] = vertices[5, 2] = 0;

            for (var i = 0; i < vertices.Height; ++i)
            {
                vertices[i, 3] = 1;
            }

            var faces = new MyMatrix <int>(new int[, ]
            {
                { 1, 0, 4 },
                { 2, 1, 4 },
                { 3, 2, 4 },
                { 0, 3, 4 },
                { 0, 1, 5 },
                { 1, 2, 5 },
                { 2, 3, 5 },
                { 3, 0, 5 }
            });

            return(new Mesh(faces, vertices));
        }
Exemplo n.º 14
0
        public IList <Face> GetVisibleFaces(double x, double y, double z)
        {
            //var inversedMatrix = Utilities.Inverse(m_rotation);
            //var inversedMatrix = m_rotation;
            //var vertices = m_vertices;
            var vertices = GetWorldCoordinates();

            double barycenterX = 0;
            double barycenterY = 0;
            double barycenterZ = 0;

            for (var i = 0; i < vertices.Height; ++i)
            {
                barycenterX += vertices[i, 0];
                barycenterY += vertices[i, 1];
                barycenterZ += vertices[i, 2];
            }
            barycenterX /= vertices.Height;
            barycenterY /= vertices.Height;
            barycenterZ /= vertices.Height;

            IList <Face> result = new List <Face>();
            var          planes = new MyMatrix <double>(4, Faces.Count);

            for (var i = 0; i < Faces.Count; ++i)
            {
                var x1 = vertices[Faces[i].Indices[1], 0] - vertices[Faces[i].Indices[0], 0];
                var y1 = vertices[Faces[i].Indices[1], 1] - vertices[Faces[i].Indices[0], 1];
                var z1 = vertices[Faces[i].Indices[1], 2] - vertices[Faces[i].Indices[0], 2];

                var x2 = vertices[Faces[i].Indices[2], 0] - vertices[Faces[i].Indices[1], 0];
                var y2 = vertices[Faces[i].Indices[2], 1] - vertices[Faces[i].Indices[1], 1];
                var z2 = vertices[Faces[i].Indices[2], 2] - vertices[Faces[i].Indices[1], 2];

                var a = y1 * z2 - y2 * z1;
                var b = z1 * x2 - z2 * x1;
                var c = x1 * y2 - x2 * y1;
                var d = -(a * vertices[Faces[i].Indices[0], 0] + b * vertices[Faces[i].Indices[0], 1] + c * vertices[Faces[i].Indices[0], 2]);

                planes[0, i] = a;
                planes[1, i] = b;
                planes[2, i] = c;
                planes[3, i] = d;

                var sign = -Math.Sign(a * barycenterX + b * barycenterY + c * barycenterZ + d);
                if (sign == -1)
                {
                    planes[0, i] *= -1;
                    planes[1, i] *= -1;
                    planes[2, i] *= -1;
                    planes[3, i] *= -1;
                }
            }

            //planes = inversedMatrix * planes;

            for (var i = 0; i < planes.Width; ++i)
            {
                //if (planes[0, i] * (x - barycenterX) + planes[1, i] * (y - barycenterY) + planes[2, i] * (z - barycenterZ) + planes[3, i] > 0 )
                if (planes[0, i] * x + planes[1, i] * y + planes[2, i] * z + planes[3, i] > 0)
                {
                    result.Add(Faces[i]);
                }
            }

            return(result);
        }
Exemplo n.º 15
0
 public void ResetScale()
 {
     m_scale = MyMatrix <double> .Incident(4);
 }
Exemplo n.º 16
0
 public void AddScale(MyMatrix <double> scale)
 {
     m_scale = m_scale * scale;
 }
Exemplo n.º 17
0
 public void SetScale(MyMatrix <double> scale)
 {
     m_scale = scale;
 }
Exemplo n.º 18
0
 public void ResetRotation()
 {
     m_rotation = MyMatrix <double> .Incident(4);
 }
Exemplo n.º 19
0
 public void AddRotation(MyMatrix <double> rotation)
 {
     m_rotation = m_rotation * rotation;
 }
Exemplo n.º 20
0
 public void SetRotation(MyMatrix <double> rotation)
 {
     m_rotation = rotation;
 }
Exemplo n.º 21
0
 public void ResetTranslation()
 {
     m_translation = MyMatrix <double> .Incident(4);
 }
Exemplo n.º 22
0
 public void AddTranslation(MyMatrix <double> translation)
 {
     m_translation = m_translation * translation;
 }
Exemplo n.º 23
0
 public void SetTranslation(MyMatrix <double> translation)
 {
     m_translation = translation;
 }
Exemplo n.º 24
0
 public Drawer(MyMatrix <double> projection, int width, int height)
 {
     m_projection   = projection;
     m_screenWidth  = width;
     m_screenHeight = height;
 }