Exemplo n.º 1
0
        internal virtual bool ProcessBunchForRingOrientationTestOddEven_(com.epl.geometry.AttributeStreamOfInt32 bunch)
        {
            bool bModified = false;

            if (m_edges == null)
            {
                m_edges = new com.epl.geometry.RingOrientationFixer.Edges(m_shape);
            }
            if (m_unknown_nodes == null)
            {
                m_unknown_nodes = new com.epl.geometry.AttributeStreamOfInt32(0);
                m_unknown_nodes.Reserve(16);
            }
            else
            {
                m_unknown_nodes.Clear(false);
            }
            ProcessBunchForRingOrientationRemoveEdges_(bunch);
            // add edges that come into scope
            for (int i = 0, n = bunch.Size(); i < n; i++)
            {
                int vertex = bunch.Get(i);
                if (vertex == -1)
                {
                    continue;
                }
                InsertEdge_(vertex, -1);
            }
            for (int i_1 = 0; i_1 < m_unknown_nodes.Size() && m_unknown_ring_orientation_count > 0; i_1++)
            {
                int aetNode     = m_unknown_nodes.Get(i_1);
                int edge        = m_AET.GetElement(aetNode);
                int path        = m_edges.GetPath(edge);
                int orientation = m_shape.GetPathUserIndex(path, m_path_orientation_index);
                int prevPath    = -1;
                if (orientation == 0)
                {
                    int  node     = m_AET.GetPrev(aetNode);
                    int  prevNode = aetNode;
                    bool odd_even = false;
                    // find the leftmost edge for which the ring orientation is
                    // known
                    while (node != com.epl.geometry.Treap.NullNode())
                    {
                        int edge1        = m_AET.GetElement(node);
                        int path1        = m_edges.GetPath(edge1);
                        int orientation1 = m_shape.GetPathUserIndex(path1, m_path_orientation_index);
                        if (orientation1 != 0)
                        {
                            prevPath = path1;
                            break;
                        }
                        prevNode = node;
                        node     = m_AET.GetPrev(node);
                    }
                    if (node == com.epl.geometry.Treap.NullNode())
                    {
                        // if no edges have ring
                        // orientation known, then start
                        // from the left most and it has
                        // to be exterior ring.
                        odd_even = true;
                        node     = prevNode;
                    }
                    else
                    {
                        int edge1 = m_AET.GetElement(node);
                        odd_even = m_edges.IsBottomUp(edge1);
                        node     = m_AET.GetNext(node);
                        odd_even = !odd_even;
                    }
                    do
                    {
                        int edge1        = m_AET.GetElement(node);
                        int path1        = m_edges.GetPath(edge1);
                        int orientation1 = m_shape.GetPathUserIndex(path1, m_path_orientation_index);
                        if (orientation1 == 0)
                        {
                            if (odd_even != m_edges.IsBottomUp(edge1))
                            {
                                int first = m_shape.GetFirstVertex(path1);
                                m_shape.ReverseRingInternal_(first);
                                m_shape.SetLastVertex_(path1, m_shape.GetPrevVertex(first));
                                bModified = true;
                            }
                            m_shape.SetPathUserIndex(path1, m_path_orientation_index, odd_even ? 3 : 2);
                            if (!odd_even)
                            {
                                // link the holes into the linked list
                                // to mantain the OGC order.
                                int lastHole = m_shape.GetPathUserIndex(prevPath, m_path_parentage_index);
                                m_shape.SetPathUserIndex(prevPath, m_path_parentage_index, path1);
                                m_shape.SetPathUserIndex(path1, m_path_parentage_index, lastHole);
                            }
                            m_unknown_ring_orientation_count--;
                            if (m_unknown_ring_orientation_count == 0)
                            {
                                return(bModified);
                            }
                        }
                        prevPath = path1;
                        prevNode = node;
                        node     = m_AET.GetNext(node);
                        odd_even = !odd_even;
                    }while (prevNode != aetNode);
                }
            }
            return(bModified);
        }
Exemplo n.º 2
0
            internal override int Compare(com.epl.geometry.Treap treap, int left, int node)
            {
                int right = treap.GetElement(node);

                com.epl.geometry.RingOrientationFixer.Edges edges = this.m_helper.m_edges;
                double x_1;

                if (this.m_left_elm == left)
                {
                    x_1 = this.m_leftx;
                }
                else
                {
                    this.m_seg_1 = edges.GetSegment(left);
                    if (this.m_seg_1 == null)
                    {
                        com.epl.geometry.EditShape shape = edges.GetShape();
                        shape.QueryLineConnector(edges.GetStart(left), this.m_line_1);
                        this.m_seg_1 = this.m_line_1;
                        x_1          = this.m_line_1.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                    }
                    else
                    {
                        x_1 = this.m_seg_1.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                    }
                    this.m_leftx    = x_1;
                    this.m_left_elm = left;
                }
                com.epl.geometry.Segment seg_2 = edges.GetSegment(right);
                double x2;

                if (seg_2 == null)
                {
                    com.epl.geometry.EditShape shape = edges.GetShape();
                    shape.QueryLineConnector(edges.GetStart(right), this.m_line_2);
                    seg_2 = this.m_line_2;
                    x2    = this.m_line_2.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                }
                else
                {
                    x2 = seg_2.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                }
                if (x_1 == x2)
                {
                    bool bStartLower1 = edges.IsBottomUp(left);
                    bool bStartLower2 = edges.IsBottomUp(right);
                    // apparently these edges originate from same vertex and the
                    // scanline is on the vertex. move scanline a little.
                    double y1 = !bStartLower1?this.m_seg_1.GetStartY() : this.m_seg_1.GetEndY();

                    double y2 = !bStartLower2?seg_2.GetStartY() : seg_2.GetEndY();

                    double miny = System.Math.Min(y1, y2);
                    double y    = (miny + this.m_helper.m_y_scanline) * 0.5;
                    if (y == this.m_helper.m_y_scanline)
                    {
                        // assert(0);//ST: not a bug. just curious to see this
                        // happens.
                        y = miny;
                    }
                    // apparently, one of the segments is almost
                    // horizontal line.
                    x_1 = this.m_seg_1.IntersectionOfYMonotonicWithAxisX(y, 0);
                    x2  = seg_2.IntersectionOfYMonotonicWithAxisX(y, 0);
                    System.Diagnostics.Debug.Assert((x_1 != x2));
                }
                return(x_1 < x2 ? -1 : (x_1 > x2 ? 1 : 0));
            }