Esempio n. 1
0
        /// <summary>
        /// Solves the linear system A * x = b, where A is the original matrix (before the factorization),
        /// b = <paramref name="rhsVector"/> and x is the solution vector, which will be returned.
        /// </summary>
        /// <param name="rhsVector">
        /// The right hand side vector. Its <see cref="IIndexable1D.Length"/> must be equal to
        /// <see cref="Matrices.IIndexable2D.NumRows"/> of the original matrix A.
        /// </param>
        /// Thrown if the length of <paramref name="rhsVector"/> is different than <see cref="Matrices.IIndexable2D.NumRows"/>
        /// of the original matrix A.
        /// </exception>
        public static Vector SolveLinearSystem(this ITriangulation triangulation, Vector rhsVector)
        {
            var solution = Vector.CreateZero(triangulation.Order);

            triangulation.SolveLinearSystem(rhsVector, solution);
            return(solution);
        }
 public DelaunayTriangulationManager(ICoordinateValidator cv, ITriangulation triangulator)
 {
     _triangulator = triangulator;
     this.x        = cv.getX();
     this.y        = cv.getY();
     this.z_as_fxy = cv.get_Z_as_fxy();
 }
Esempio n. 3
0
    public void visualizeEdges(ITriangulation <Vector3Vertex, DefaultTriangulationCell <Vector3Vertex> > triangulation)
    {
        /*
         *
         *  foreach (var edge in voronoiMesh.Edges)
         *  {
         *      calculateCircumsphere
         *      var from = edge.Source.Circumcenter;
         *      var to = edge.Target.Circumcenter;
         *      drawingCanvas.Children.Add(new Line { X1 = from.X, Y1 = from.Y, X2 = to.X, Y2 = to.Y, Stroke = Brushes.Black });
         *  }
         *
         *  foreach (var cell in voronoiMesh.Vertices)
         *  {
         *      for (int i = 0; i < 3; i++)
         *      {
         *          if (cell.Adjacency[i] == null)
         *          {
         *              var from = cell.Circumcenter;
         *              var t = cell.Vertices.Where((_, j) => j != i).ToArray();
         *              var factor = 100 * IsLeft(t[0].ToPoint(), t[1].ToPoint(), from) * IsLeft(t[0].ToPoint(), t[1].ToPoint(), Center(cell));
         *              var dir = new Point(0.5 * (t[0].Position[0] + t[1].Position[0]), 0.5 * (t[0].Position[1] + t[1].Position[1])) - from;
         *              var to = from + factor * dir;
         *              drawingCanvas.Children.Add(new Line { X1 = from.X, Y1 = from.Y, X2 = to.X, Y2 = to.Y, Stroke = Brushes.Black });
         *          }
         *      }
         *  }
         *
         *  ShowVertices(Vertices);
         *  drawingCanvas.Children.Add(new Rectangle { Width = drawingCanvas.ActualWidth, Height = drawingCanvas.ActualHeight, Stroke = Brushes.Black, StrokeThickness = 3 });
         * }
         */



        // visualize
        foreach (var cell in triangulation.Cells)
        {
            for (int i = 0; i < cell.Adjacency.Length; i++)
            {
                var F = cell.Adjacency[i];
                int sharedBoundaries = 0;
                // vertices shared with F:
                for (int j = 0; j < cell.Vertices.Length; j++)
                {
                    if (i != j)
                    {
                        sharedBoundaries++;
                        //cell.Vertices[j]
                    }
                }
                Debug.Log("Shared vertices: " + sharedBoundaries);
            }


//                    drawLine(lastPos, vertex.toVector3(), ColorAssistant.getQualitativeColor(0));
        }
    }
Esempio n. 4
0
        /// <summary>
        /// Provide new values for the vertices that constitute the triangles of the specified face.
        /// </summary>
        /// <param name="face">The face whose triangle vertices should be udpated.</param>
        /// <param name="triangulation">The triangulation method used for converting faces to triangles.</param>
        /// <remarks>
        /// <para>This method will update the vertex attribute values for this face, but will not
        /// immediately push these changes to the mesh itself.  Instead, it will simply mark the
        /// relevant submesh as dirty.  Call <see cref="RebuildMesh"/>() in order to commit all
        /// changes and apply them to the mesh.</para>
        ///
        /// <para>The <paramref name="triangulation"/> parameter is expected to match the kind of
        /// triangulation used when first creating the dynamic mesh, but is permitted to set the
        /// vertex attributes however it likes.  That is, the number of triangles generated for
        /// each face and the vertex indices used by each of these triangles cannot change, only
        /// vertex attributes.  Not all vertex attributes need or are always expected to be
        /// changed either.  In many cases, simply changing normals or uvs, for example, is
        /// all that is needed, and all other vertex attribute values can remain the same.</para>
        /// </remarks>
        public void RebuildFace(Topology.Face face, ITriangulation triangulation)
        {
            var submesh = _submeshes[_faceSubmeshIndices[face.index]];
            var vertexAttributeArrays = GetIndexedVertexAttributeArrays(submesh, _faceFirstVertexIndices[face.index]);

            triangulation.RebuildFace(face, vertexAttributeArrays);

            submesh.isDirty = true;
        }
Esempio n. 5
0
        /// <summary>
        /// Ring:划分Delaunay三角网,结果保存于tsData
        /// </summary>
        /// <param name="depth">深度</param>
        /// <param name="interpolateFunc">插值函数</param>
        public void MeshRing(
            double depth,
            Func <IList <Point>, double, double, double, double> interpolateFunc)
        {
            try
            {
                triangulations = Triangulation.CreateDelaunay(this.allVerticesList);


                this.TsData.VerticesList = new List <Point3D>(this.allVerticesList.Count);
                this.TsData.TriLinksList = new List <TriLink>(this.triangulations.Cells.Count());

                // 以Dict记录三角形的编号
                int num = 1;
                foreach (var cell in this.triangulations.Cells)
                {
                    for (int i = 0; i < 3; ++i)
                    {
                        var v = cell.Vertices[i];
                        if (!this.vertexnumDictionary.ContainsKey(v))
                        {
                            this.vertexnumDictionary.Add(v, num++);
                        }
                    }

                    // 根据编号写ts的TriLinksList
                    this.TsData.TriLinksList.Add(new TriLink
                    {
                        VertexA = this.vertexnumDictionary[cell.Vertices[0]],
                        VertexB = this.vertexnumDictionary[cell.Vertices[1]],
                        VertexC = this.vertexnumDictionary[cell.Vertices[2]]
                    });
                }

                // 写ts的VerticesList, 并插值Z
                foreach (var kv in this.vertexnumDictionary.OrderBy(n => n.Value))
                {
                    var vPos = kv.Key.Position;
                    var x    = vPos[0];
                    var y    = vPos[1];
                    var z    = interpolateFunc(this.edgeVerticesList, depth, x, y);

                    this.TsData.VerticesList.Add(new Point3D(x, y, z));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }
Esempio n. 6
0
 public void visualizeVertices(ITriangulation <Vector3Vertex, DefaultTriangulationCell <Vector3Vertex> > triangulation)
 {
     // visualize
     foreach (var cell in triangulation.Cells)
     {
         foreach (var vertex in cell.Vertices)
         {
             GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
             sphere.transform.position   = vertex.toVector3();
             sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
             sphere.transform.SetParent(_delaunay.transform);
             setColor(sphere, ColorAssistant.getQualitativeColor(0));
         }
     }
 }
Esempio n. 7
0
        /// <summary>
        /// Creates a dynamic mesh instance for the given faces, using the specified vertex attributes and triangulation object to construct the vertex data and triangles.
        /// </summary>
        /// <param name="faces">The faces for which to generate triangle meshes.</param>
        /// <param name="vertexAttributes">The types of vertex data to include in the meshes, such as position, color, and normal.</param>
        /// <param name="triangulation">The object which is responsible for turning each individual face into triangles with a mesh.</param>
        /// <param name="maxVerticesPerSubmesh">The maximum number of vertices allowed per submesh.  Defaults to Unity's built-in maximum of 65534.</param>
        /// <returns>A dynamic mesh instance created from the given faces and triangulation.</returns>
        public static DynamicMesh Create(IEnumerable <Topology.Face> faces, VertexAttributes vertexAttributes, ITriangulation triangulation, int maxVerticesPerSubmesh = 65534)
        {
            var dynamicMesh = CreateInstance <DynamicMesh>();

            dynamicMesh._vertexAttributes      = vertexAttributes;
            dynamicMesh._maxVerticesPerSubmesh = maxVerticesPerSubmesh;
            dynamicMesh.Initialize(new IEnumerable <Topology.Face>[] { faces }, triangulation);
            return(dynamicMesh);
        }
Esempio n. 8
0
        private void Initialize(IEnumerable <IEnumerable <Topology.Face> > faceGroups, ITriangulation triangulation)
        {
            int maxFaceIndex = -1;
            var dynamicFaceSubmeshIndicesArray     = new int[65536];
            var dynamicFaceFirstVertexIndicesArray = new int[65536];

            _cachedIndexedVertexAttributeArrays = new IndexedVertexAttributeArrays();

            var submeshList = new List <Submesh>();

            var vertexAttributeArrays = new DynamicVertexAttributeArrays(_vertexAttributes, _maxVerticesPerSubmesh);
            var triangleIndices       = new List <int>();

            foreach (var faceGroup in faceGroups)
            {
                foreach (var face in faceGroup)
                {
                    var vertexCount = triangulation.GetVertexCount(face);

                    if (vertexAttributeArrays.index + vertexCount > _maxVerticesPerSubmesh)
                    {
                        triangulation.FinalizeSubmesh(submeshList.Count);
                        submeshList.Add(new Submesh(vertexAttributeArrays, triangleIndices));
                        vertexAttributeArrays.Reset();
                        triangleIndices.Clear();
                    }

                    maxFaceIndex = Mathf.Max(maxFaceIndex, face.index);
                    SetGrowableArrayElement(ref dynamicFaceSubmeshIndicesArray, face.index, submeshList.Count);
                    SetGrowableArrayElement(ref dynamicFaceFirstVertexIndicesArray, face.index, vertexAttributeArrays.index);

                    vertexAttributeArrays.Grow(vertexCount);

                    triangulation.BuildFace(face, vertexAttributeArrays, triangleIndices);
                }

                if (vertexAttributeArrays.index > 0)
                {
                    triangulation.FinalizeSubmesh(submeshList.Count);
                    submeshList.Add(new Submesh(vertexAttributeArrays, triangleIndices));
                    vertexAttributeArrays.Reset();
                    triangleIndices.Clear();
                }
            }

            _submeshes = submeshList.ToArray();

            var faceCount = maxFaceIndex + 1;

            _faceSubmeshIndices     = new int[faceCount];
            _faceFirstVertexIndices = new int[faceCount];
            Array.Copy(dynamicFaceSubmeshIndicesArray, _faceSubmeshIndices, faceCount);
            Array.Copy(dynamicFaceFirstVertexIndicesArray, _faceFirstVertexIndices, faceCount);
        }
Esempio n. 9
0
        /// <summary>
        /// Calculates the Schur complement of M/C = S = A - B^T * inv(C) * B, where M = [A B; B^T C].
        /// This method constructs inv(C) * B one column at a time and uses that column to calculate the superdiagonal
        /// entries of the corresponding column of B^T * inv(C) * B.
        /// </summary>
        public static SymmetricMatrix CalcSchurComplementSymmetric(SymmetricMatrix A, CscMatrix B, ITriangulation inverseC)
        { //TODO: Unfortunately this cannot take advantage of MKL for CSC^T * vector.
            double[] valuesB     = B.RawValues;
            int[]    rowIndicesB = B.RawRowIndices;
            int[]    colOffsetsB = B.RawColOffsets;
            var      S           = SymmetricMatrix.CreateZero(A.Order);

            for (int j = 0; j < B.NumColumns; ++j)
            {
                // column j of (inv(C) * B) = inv(C) * column j of B
                Vector   colB     = B.GetColumn(j);
                double[] colInvCB = inverseC.SolveLinearSystem(colB).RawData;

                // column j of (B^T * inv(C) * B) = B^T * column j of (inv(C) * B)
                // However we only need the superdiagonal part of this column.
                // Thus we only multiply the rows i of B^T (stored as columns i of B) with i <= j.
                for (int i = 0; i <= j; ++i)
                {
                    double dot      = 0.0;
                    int    colStart = colOffsetsB[i];     //inclusive
                    int    colEnd   = colOffsetsB[i + 1]; //exclusive
                    for (int k = colStart; k < colEnd; ++k)
                    {
                        dot += valuesB[k] * colInvCB[rowIndicesB[k]];
                    }

                    // Perform the subtraction S = A - (B^T * inv(C) * B) for the current (i, j)
                    int indexS = S.Find1DIndex(i, j);
                    S.RawData[indexS] = A.RawData[indexS] - dot;
                }
            }

            return(S);
        }