private void Next_(int action)
        {
            switch (m_functionStack.GetLast())
            {
            case com.epl.geometry.JsonWriter.State.accept:
            {
                Accept_(action);
                break;
            }

            case com.epl.geometry.JsonWriter.State.start:
            {
                Start_(action);
                break;
            }

            case com.epl.geometry.JsonWriter.State.objectStart:
            {
                ObjectStart_(action);
                break;
            }

            case com.epl.geometry.JsonWriter.State.arrayStart:
            {
                ArrayStart_(action);
                break;
            }

            case com.epl.geometry.JsonWriter.State.pairEnd:
            {
                PairEnd_(action);
                break;
            }

            case com.epl.geometry.JsonWriter.State.elementEnd:
            {
                ElementEnd_(action);
                break;
            }

            case com.epl.geometry.JsonWriter.State.fieldNameEnd:
            {
                FieldNameEnd_(action);
                break;
            }

            default:
            {
                throw new com.epl.geometry.GeometryException("internal error");
            }
            }
        }
        private void GeneralizePath(com.epl.geometry.MultiPathImpl mpsrc, int ipath, com.epl.geometry.MultiPathImpl mpdst, com.epl.geometry.Line lineHelper)
        {
            if (mpsrc.GetPathSize(ipath) < 2)
            {
                return;
            }
            int start = mpsrc.GetPathStart(ipath);
            int end   = mpsrc.GetPathEnd(ipath) - 1;

            com.epl.geometry.AttributeStreamOfDbl xy = (com.epl.geometry.AttributeStreamOfDbl)mpsrc.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION);
            bool bClosed = mpsrc.IsClosedPath(ipath);

            com.epl.geometry.AttributeStreamOfInt32 stack = new com.epl.geometry.AttributeStreamOfInt32(0);
            stack.Reserve(mpsrc.GetPathSize(ipath) + 1);
            com.epl.geometry.AttributeStreamOfInt32 resultStack = new com.epl.geometry.AttributeStreamOfInt32(0);
            resultStack.Reserve(mpsrc.GetPathSize(ipath) + 1);
            stack.Add(bClosed ? start : end);
            stack.Add(start);
            com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
            while (stack.Size() > 1)
            {
                int i1 = stack.GetLast();
                stack.RemoveLast();
                int i2 = stack.GetLast();
                mpsrc.GetXY(i1, pt);
                lineHelper.SetStartXY(pt);
                mpsrc.GetXY(i2, pt);
                lineHelper.SetEndXY(pt);
                int mid = FindGreatestDistance(lineHelper, pt, xy, i1, i2, end);
                if (mid >= 0)
                {
                    stack.Add(mid);
                    stack.Add(i1);
                }
                else
                {
                    resultStack.Add(i1);
                }
            }
            if (!bClosed)
            {
                resultStack.Add(stack.Get(0));
            }
            int rs_size   = resultStack.Size();
            int path_size = mpsrc.GetPathSize(ipath);

            if (rs_size == path_size && rs_size == stack.Size())
            {
                mpdst.AddPath(mpsrc, ipath, true);
            }
            else
            {
                if (resultStack.Size() > 0)
                {
                    if (m_bRemoveDegenerateParts && resultStack.Size() <= 2)
                    {
                        if (bClosed || resultStack.Size() == 1)
                        {
                            return;
                        }
                        double d = com.epl.geometry.Point2D.Distance(mpsrc.GetXY(resultStack.Get(0)), mpsrc.GetXY(resultStack.Get(1)));
                        if (d <= m_maxDeviation)
                        {
                            return;
                        }
                    }
                    com.epl.geometry.Point point = new com.epl.geometry.Point();
                    for (int i = 0, n = resultStack.Size(); i < n; i++)
                    {
                        mpsrc.GetPointByVal(resultStack.Get(i), point);
                        if (i == 0)
                        {
                            mpdst.StartPath(point);
                        }
                        else
                        {
                            mpdst.LineTo(point);
                        }
                    }
                    if (bClosed)
                    {
                        for (int i_1 = resultStack.Size(); i_1 < 3; i_1++)
                        {
                            mpdst.LineTo(point);
                        }
                        mpdst.ClosePathWithLine();
                    }
                }
            }
        }
Пример #3
0
        internal virtual bool FixRingSelfTangency_()
        {
            com.epl.geometry.AttributeStreamOfInt32 self_tangent_paths     = new com.epl.geometry.AttributeStreamOfInt32(0);
            com.epl.geometry.AttributeStreamOfInt32 self_tangency_clusters = new com.epl.geometry.AttributeStreamOfInt32(0);
            int tangent_path_first_vertex_index = -1;
            int tangent_vertex_cluster_index    = -1;

            com.epl.geometry.Point2D pt_prev = new com.epl.geometry.Point2D();
            pt_prev.SetNaN();
            int prev_vertex     = -1;
            int old_path        = -1;
            int current_cluster = -1;

            com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
            for (int ivertex = m_sorted_vertices.GetFirst(m_sorted_vertices.GetFirstList()); ivertex != -1; ivertex = m_sorted_vertices.GetNext(ivertex))
            {
                int vertex = m_sorted_vertices.GetData(ivertex);
                m_shape.GetXY(vertex, pt);
                int path = m_shape.GetPathFromVertex(vertex);
                if (pt_prev.IsEqual(pt) && old_path == path)
                {
                    if (tangent_vertex_cluster_index == -1)
                    {
                        tangent_path_first_vertex_index = m_shape.CreatePathUserIndex();
                        tangent_vertex_cluster_index    = m_shape.CreateUserIndex();
                    }
                    if (current_cluster == -1)
                    {
                        current_cluster = self_tangency_clusters.Size();
                        m_shape.SetUserIndex(prev_vertex, tangent_vertex_cluster_index, current_cluster);
                        self_tangency_clusters.Add(1);
                        int p = m_shape.GetPathUserIndex(path, tangent_path_first_vertex_index);
                        if (p == -1)
                        {
                            m_shape.SetPathUserIndex(path, tangent_path_first_vertex_index, prev_vertex);
                            self_tangent_paths.Add(path);
                        }
                    }
                    m_shape.SetUserIndex(vertex, tangent_vertex_cluster_index, current_cluster);
                    self_tangency_clusters.SetLast(self_tangency_clusters.GetLast() + 1);
                }
                else
                {
                    current_cluster = -1;
                    pt_prev.SetCoords(pt);
                }
                prev_vertex = vertex;
                old_path    = path;
            }
            if (self_tangent_paths.Size() == 0)
            {
                return(false);
            }
            // Now self_tangent_paths contains list of clusters of tangency for each
            // path.
            // The clusters contains list of clusters and for each cluster it
            // contains a list of vertices.
            com.epl.geometry.AttributeStreamOfInt32 vertex_stack  = new com.epl.geometry.AttributeStreamOfInt32(0);
            com.epl.geometry.AttributeStreamOfInt32 cluster_stack = new com.epl.geometry.AttributeStreamOfInt32(0);
            for (int ipath = 0, npath = self_tangent_paths.Size(); ipath < npath; ipath++)
            {
                int path         = self_tangent_paths.Get(ipath);
                int first_vertex = m_shape.GetPathUserIndex(path, tangent_path_first_vertex_index);
                int cluster      = m_shape.GetUserIndex(first_vertex, tangent_vertex_cluster_index);
                vertex_stack.Clear(false);
                cluster_stack.Clear(false);
                vertex_stack.Add(first_vertex);
                cluster_stack.Add(cluster);
                for (int vertex = m_shape.GetNextVertex(first_vertex); vertex != first_vertex; vertex = m_shape.GetNextVertex(vertex))
                {
                    int vertex_to  = vertex;
                    int cluster_to = m_shape.GetUserIndex(vertex_to, tangent_vertex_cluster_index);
                    if (cluster_to != -1)
                    {
                        if (cluster_stack.Size() == 0)
                        {
                            cluster_stack.Add(cluster_to);
                            vertex_stack.Add(vertex_to);
                            continue;
                        }
                        if (cluster_stack.GetLast() == cluster_to)
                        {
                            int vertex_from = vertex_stack.GetLast();
                            // peel the loop from path
                            int from_next = m_shape.GetNextVertex(vertex_from);
                            int from_prev = m_shape.GetPrevVertex(vertex_from);
                            int to_next   = m_shape.GetNextVertex(vertex_to);
                            int to_prev   = m_shape.GetPrevVertex(vertex_to);
                            m_shape.SetNextVertex_(vertex_from, to_next);
                            m_shape.SetPrevVertex_(to_next, vertex_from);
                            m_shape.SetNextVertex_(vertex_to, from_next);
                            m_shape.SetPrevVertex_(from_next, vertex_to);
                            // vertex_from is left in the path we are processing,
                            // while the vertex_to is in the loop being teared off.
                            bool[] first_vertex_correction_requied = new bool[] { false };
                            int    new_path = m_shape.InsertClosedPath_(m_geometry, -1, from_next, m_shape.GetFirstVertex(path), first_vertex_correction_requied);
                            m_shape.SetUserIndex(vertex, tangent_vertex_cluster_index, -1);
                            // Fix the path after peeling if the peeled loop had the
                            // first path vertex in it
                            if (first_vertex_correction_requied[0])
                            {
                                m_shape.SetFirstVertex_(path, to_next);
                            }
                            int path_size     = m_shape.GetPathSize(path);
                            int new_path_size = m_shape.GetPathSize(new_path);
                            path_size -= new_path_size;
                            System.Diagnostics.Debug.Assert((path_size >= 3));
                            m_shape.SetPathSize_(path, path_size);
                            self_tangency_clusters.Set(cluster_to, self_tangency_clusters.Get(cluster_to) - 1);
                            if (self_tangency_clusters.Get(cluster_to) == 1)
                            {
                                self_tangency_clusters.Set(cluster_to, 0);
                                cluster_stack.RemoveLast();
                                vertex_stack.RemoveLast();
                            }
                            // this cluster has more than two vertices in it.
                            first_vertex = vertex_from;
                            // reset the counter to
                            // ensure we find all loops.
                            vertex = vertex_from;
                        }
                        else
                        {
                            vertex_stack.Add(vertex);
                            cluster_stack.Add(cluster_to);
                        }
                    }
                }
            }
            m_shape.RemovePathUserIndex(tangent_path_first_vertex_index);
            m_shape.RemoveUserIndex(tangent_vertex_cluster_index);
            return(true);
        }