Пример #1
0
        EdgesRing GetTriangulationsClosedBoundary()
        {
            var  boundary = new EdgesRing();
            Edge vertice  = _rightExtremeTriangle.Edges[1];

            for (int i = 0; i < 3; i++)
            {
                _triangles.Remove(vertice.IncludingTriangle);
                while (vertice.MirrorOut.NextIn.MirrorOut != null)
                {
                    vertice = vertice.MirrorOut.NextIn;
                    boundary.AddDataToEnd(vertice.NextIn);
                }
                vertice = vertice.MirrorOut.NextIn.NextIn;
            }
            return(boundary);
        }
Пример #2
0
        void Triangulate()
        {
            #region Local Fields

            Edge           firstVertice, secondVertice = null;
            TriangleBranch containingTriangleRoot       = new TriangleBranch(),
                           mirrorContainingTriangleRoot = new TriangleBranch();
            var boundary = new List <Tuple <Edge, TriangleBranch> >();
            Tuple <Edge, Edge> adjacentVertices = null;

            #endregion // End of Local Fields

            #region Rearrange data (I)

            _points.Sort(_yComparer);

            double xmin = _points.Min(p => p.X),
                   xmax = _points.Max(p => p.X),
                   ymin = _points[0].Y,
                   ymax = _points[_points.Count - 1].Y,
                   xo   = (xmax + xmin) / 2D,
                   yo   = (ymax + ymin) / 2D,
                   xdis = Math.Floor(xo),
                   ydis = Math.Floor(yo);

            foreach (Vertex point in _points)
            {
                point.X -= xdis;
                point.Y -= ydis;
            }

            xmin -= xdis;
            ymin -= ydis;
            xo   -= xdis;
            yo   -= ydis;

            #endregion // End of Rearrange data (I)

            #region Create container triangle

            double radious = (RadiousIncreaseByPercent + 1) * Math.Sqrt(Math.Pow(xo - xmin, 2) + Math.Pow(yo - ymin, 2)),
                   diam    = 2 * radious,
                   height  = radious * Math.Sqrt(3);

            _k = new Vertex(xo, yo + diam, 0);
            _l = new Vertex(xo - height, yo - radious, 0);
            _m = new Vertex(xo + height, yo - radious, 0);

            _triangles.Add(new Triangle(_k, _l, _m, new List <Vertex>(_points)));
            _rightExtremeTriangle = _triangles[0];

            #endregion // End of Create container triangle

            #region Construct the mesh of points

            foreach (Vertex point in _points)
            {
                Triangle containingTriangle = TriangleIncluding(point);
                containingTriangle.VerticesIncluded.Remove(point);
                containingTriangleRoot.Node         = containingTriangle;
                containingTriangleRoot.PreviousNode = null;

                int  i, j = i = 0;
                bool found = false;
                do
                {
                    if (containingTriangle.Edges[i].EndVertex == _k)
                    {
                        found = true;
                    }
                    else
                    {
                        i++;
                    }
                }while (!found);

                found = false;
                do
                {
                    if (point.IsRelativeToLine(containingTriangle.Edges[j])
                        == VertexVectorOrientation.Colinear)
                    {
                        found = true;
                    }
                    else
                    {
                        j++;
                    }
                }while (!found && j < 3);

                if (found)
                {
                    for (int k = i; k < i + 3; k++)
                    {
                        if (k == j)
                        {
                            if (containingTriangle.Edges[j].MirrorOut != null)
                            {
                                firstVertice = containingTriangle.Edges[j].MirrorOut;
                                CreateLocalTriangulationsBoundary(boundary, containingTriangleRoot, firstVertice.NextIn, point);
                                mirrorContainingTriangleRoot.Node         = firstVertice.IncludingTriangle;
                                mirrorContainingTriangleRoot.PreviousNode = null;
                                CreateLocalTriangulationsBoundary(boundary, mirrorContainingTriangleRoot, firstVertice.NextIn.NextIn, point);
                                _triangles.Remove(firstVertice.IncludingTriangle);
                            }
                            else
                            {
                                boundary.Add(new Tuple <Edge, TriangleBranch>(containingTriangle.Edges[j], containingTriangleRoot));
                            }
                        }
                        else
                        {
                            CreateLocalTriangulationsBoundary(boundary, containingTriangleRoot, containingTriangle.Edges[k % 3], point);
                        }
                    }
                }
                else
                {
                    for (j = i; j < i + 3; j++)
                    {
                        CreateLocalTriangulationsBoundary(boundary, containingTriangleRoot, containingTriangle.Edges[j % 3], point);
                    }
                }
                _triangles.Remove(containingTriangle);

                Tuple <Edge, Edge> previousAdjacentVertices = AddSlice(boundary[0], point);
                firstVertice = previousAdjacentVertices.Item1;
                for (i = 1; i < boundary.Count; i++)
                {
                    adjacentVertices = AddSlice(boundary[i], point);
                    adjacentVertices.Item1.ConnectWithMirror(previousAdjacentVertices.Item2);
                    previousAdjacentVertices = adjacentVertices;
                }
                adjacentVertices.Item2.ConnectWithMirror(firstVertice);

                boundary.Clear();
            }

            #endregion // End of Construct the mesh of points

            #region Envelope in closed curved boundary

            EdgesRing closedBoundary = GetTriangulationsClosedBoundary();
            closedBoundary.CurvePath();
            closedBoundary.Triangulate(_triangles);

            #endregion // End of Envelope in closed curved boundary

            #region Apply edge constrains

            if (!(_constrains == null || _constrains.Count == 0))
            {
                foreach (Tuple <Vertex, Vertex> constrain in _constrains)
                {
                    if (!_points.Contains(constrain.Item1, _pComparer) ||
                        !_points.Contains(constrain.Item2, _pComparer))
                    {
                        continue;
                    }
                    List <Tuple <EdgesPath, EdgesPath> > sequencesPairs = GetSequences(constrain.Item1, constrain.Item2);
                    if (sequencesPairs == null)
                    {
                        continue;
                    }
                    foreach (Tuple <EdgesPath, EdgesPath> pair in sequencesPairs)
                    {
                        firstVertice = null;
                        if (pair.Item1.Path.Count > 0)
                        {
                            firstVertice = pair.Item1.Triangulate(_triangles);
                        }
                        if (pair.Item2.Path.Count > 0)
                        {
                            secondVertice = pair.Item2.Triangulate(_triangles);
                        }
                        if (firstVertice != null && secondVertice != null)
                        {
                            firstVertice.ConnectWithMirror(secondVertice);
                        }
                    }
                }
            }

            #endregion // End of Apply edge constrains

            #region Rearrange data (II)

            foreach (Vertex point in _points)
            {
                point.X += xdis;
                point.Y += ydis;
            }

            #endregion // End of Rearrange data (II)
        }