Ejemplo n.º 1
0
        void CreateLocalTriangulationsBoundary(List <Tuple <Edge, TriangleBranch> > boundary,
                                               TriangleBranch previousBranch, Edge vertice, Vertex point)
        {
            if (vertice.MirrorOut != null)
            {
                VertexCircleRelation relation = vertice.MirrorOut.NextIn.EndVertex.
                                                IsRelativeToCircle(vertice.EndVertex, point, vertice.StartVertex);

                if (relation == VertexCircleRelation.Outside ||
                    relation == VertexCircleRelation.Cocircular)
                {
                    boundary.Add(new Tuple <Edge, TriangleBranch>(vertice, previousBranch));
                }
                else
                {
                    var branch = new TriangleBranch(vertice.MirrorOut.IncludingTriangle, previousBranch);
                    CreateLocalTriangulationsBoundary(boundary, branch, vertice.MirrorOut.NextIn, point);
                    CreateLocalTriangulationsBoundary(boundary, branch, vertice.MirrorOut.NextIn.NextIn, point);
                    _triangles.Remove(vertice.MirrorOut.IncludingTriangle);
                }
            }
            else
            {
                boundary.Add(new Tuple <Edge, TriangleBranch>(vertice, previousBranch));
            }
        }
Ejemplo n.º 2
0
        Tuple <Edge, Edge> AddSlice(Tuple <Edge, TriangleBranch> bound, Vertex point)
        {
            Edge           vertice = bound.Item1;
            TriangleBranch branch  = bound.Item2;

            var slice = new Triangle(vertice, point, 0, true);

            do
            {
                int j = 0;
                while (j < branch.Node.VerticesIncluded.Count)
                {
                    Vertex pointToInclude      = branch.Node.VerticesIncluded[j];
                    VertexVectorOrientation o1 = pointToInclude.IsRelativeToLine(vertice.NextIn),
                                            o2 = pointToInclude.IsRelativeToLine(vertice.NextIn.NextIn);

                    if ((o2 == VertexVectorOrientation.ToTheLeftOf ||
                         o2 == VertexVectorOrientation.Colinear) &&
                        o1 == VertexVectorOrientation.ToTheLeftOf)
                    {
                        slice.VerticesIncluded.Add(pointToInclude);
                        branch.Node.VerticesIncluded.Remove(pointToInclude);
                    }
                    else
                    {
                        j++;
                    }
                }
                branch = branch.PreviousNode;
            }while (branch != null);

            _triangles.Add(slice);
            if (vertice.StartVertex == _m && vertice.EndVertex == _k)
            {
                _rightExtremeTriangle = slice;
            }

            return(new Tuple <Edge, Edge>(slice.Edges[2], slice.Edges[1]));
        }
Ejemplo n.º 3
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)
        }