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); }
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)); }