private ConvexHull(com.epl.geometry.AttributeStreamOfDbl stream, int n) { m_tree_hull = new com.epl.geometry.Treap(); m_tree_hull.SetCapacity(System.Math.Min(20, n)); m_stream = stream; m_call_back = new com.epl.geometry.ConvexHull.CallBackStream(this); }
private ConvexHull(com.epl.geometry.Point2D[] points, int n) { m_tree_hull = new com.epl.geometry.Treap(); m_tree_hull.SetCapacity(System.Math.Min(20, n)); m_points = points; m_call_back = new com.epl.geometry.ConvexHull.CallBackPoints(this); }
internal RingOrientationFixer() { m_AET = new com.epl.geometry.Treap(); m_AET.DisableBalancing(); m_sweep_comparator = new com.epl.geometry.RingOrientationFixer.RingOrientationTestComparator(this, this); m_AET.SetComparator(m_sweep_comparator); }
internal virtual void OnSetImpl_(com.epl.geometry.Treap treap, int node) { if (m_b_notify_on_actions) { OnSet(treap.GetElement(node)); } }
internal ConvexHull() { /* * Constructor for a Convex_hull object. Used for dynamic insertion of geometries to create a convex hull. */ m_tree_hull = new com.epl.geometry.Treap(); m_tree_hull.SetCapacity(20); m_shape = new com.epl.geometry.EditShape(); m_geometry_handle = m_shape.CreateGeometry(com.epl.geometry.Geometry.Type.MultiPoint); m_path_handle = m_shape.InsertPath(m_geometry_handle, -1); m_call_back = new com.epl.geometry.ConvexHull.CallBackShape(this); }
internal override int Compare(com.epl.geometry.Treap treap, int elm, int node) { int elm2 = treap.GetElement(node); com.epl.geometry.Point2D pt1 = m_pts[elm]; com.epl.geometry.Point2D pt2 = m_pts[elm2]; if (pt1.x < pt2.x) { return(-1); } return(1); }
// The compare method. Compares x values of the edge given by its origin // (elm) and the edge in the sweep structure and checks them for // intersection at the same time. internal override int Compare(com.epl.geometry.Treap treap, int left, int node) { // Compares two segments on a sweep line passing through m_sweep_y, // m_sweep_x. if (m_b_intersection_detected) { return(-1); } int right = treap.GetElement(node); m_current_node = node; return(CompareSegments(left, left, right, right)); }
public static void Test1() { com.epl.geometry.Point2D[] pts = new com.epl.geometry.Point2D[10]; for (int i = 0; i < 10; i++) { com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); pt.x = i; pt.y = 0; pts[i] = pt; } com.epl.geometry.TreapComparatorForTesting c = new com.epl.geometry.TreapComparatorForTesting(pts); com.epl.geometry.Treap treap = new com.epl.geometry.Treap(); treap.SetComparator(c); int[] nodes = new int[10]; for (int i_1 = 0; i_1 < 10; i_1++) { nodes[i_1] = treap.AddElement(i_1, -1); } for (int i_2 = 1; i_2 < 10; i_2++) { NUnit.Framework.Assert.IsTrue(treap.GetPrev(nodes[i_2]) == nodes[i_2 - 1]); } for (int i_3 = 0; i_3 < 9; i_3++) { NUnit.Framework.Assert.IsTrue(treap.GetNext(nodes[i_3]) == nodes[i_3 + 1]); } treap.DeleteNode(nodes[0], -1); treap.DeleteNode(nodes[2], -1); treap.DeleteNode(nodes[4], -1); treap.DeleteNode(nodes[6], -1); treap.DeleteNode(nodes[8], -1); NUnit.Framework.Assert.IsTrue(treap.GetPrev(nodes[3]) == nodes[1]); NUnit.Framework.Assert.IsTrue(treap.GetPrev(nodes[5]) == nodes[3]); NUnit.Framework.Assert.IsTrue(treap.GetPrev(nodes[7]) == nodes[5]); NUnit.Framework.Assert.IsTrue(treap.GetPrev(nodes[9]) == nodes[7]); NUnit.Framework.Assert.IsTrue(treap.GetNext(nodes[1]) == nodes[3]); NUnit.Framework.Assert.IsTrue(treap.GetNext(nodes[3]) == nodes[5]); NUnit.Framework.Assert.IsTrue(treap.GetNext(nodes[5]) == nodes[7]); NUnit.Framework.Assert.IsTrue(treap.GetNext(nodes[7]) == nodes[9]); }
internal bool NeedsCrackingImpl_() { bool b_needs_cracking = false; if (m_sweep_structure == null) { m_sweep_structure = new com.epl.geometry.Treap(); } com.epl.geometry.AttributeStreamOfInt32 event_q = new com.epl.geometry.AttributeStreamOfInt32(0); event_q.Reserve(m_shape.GetTotalPointCount() + 1); com.epl.geometry.EditShape.VertexIterator iter = m_shape.QueryVertexIterator(); for (int vert = iter.Next(); vert != -1; vert = iter.Next()) { event_q.Add(vert); } System.Diagnostics.Debug.Assert((m_shape.GetTotalPointCount() == event_q.Size())); m_shape.SortVerticesSimpleByY_(event_q, 0, event_q.Size()); event_q.Add(-1); // for termination; // create user indices to store edges that end at vertices. int edge_index_1 = m_shape.CreateUserIndex(); int edge_index_2 = m_shape.CreateUserIndex(); m_sweep_comparator = new com.epl.geometry.SweepComparator(m_shape, m_tolerance, !m_bAllowCoincident); m_sweep_structure.SetComparator(m_sweep_comparator); com.epl.geometry.AttributeStreamOfInt32 swept_edges_to_delete = new com.epl.geometry.AttributeStreamOfInt32(0); com.epl.geometry.AttributeStreamOfInt32 edges_to_insert = new com.epl.geometry.AttributeStreamOfInt32(0); // Go throught the sorted vertices int event_q_index = 0; com.epl.geometry.Point2D cluster_pt = new com.epl.geometry.Point2D(); // sweep-line algorithm: for (int vertex = event_q.Get(event_q_index++); vertex != -1;) { m_shape.GetXY(vertex, cluster_pt); do { int next_vertex = m_shape.GetNextVertex(vertex); int prev_vertex = m_shape.GetPrevVertex(vertex); if (next_vertex != -1 && m_shape.CompareVerticesSimpleY_(vertex, next_vertex) < 0) { edges_to_insert.Add(vertex); edges_to_insert.Add(next_vertex); } if (prev_vertex != -1 && m_shape.CompareVerticesSimpleY_(vertex, prev_vertex) < 0) { edges_to_insert.Add(prev_vertex); edges_to_insert.Add(prev_vertex); } // Continue accumulating current cluster int attached_edge_1 = m_shape.GetUserIndex(vertex, edge_index_1); if (attached_edge_1 != -1) { swept_edges_to_delete.Add(attached_edge_1); m_shape.SetUserIndex(vertex, edge_index_1, -1); } int attached_edge_2 = m_shape.GetUserIndex(vertex, edge_index_2); if (attached_edge_2 != -1) { swept_edges_to_delete.Add(attached_edge_2); m_shape.SetUserIndex(vertex, edge_index_2, -1); } vertex = event_q.Get(event_q_index++); }while (vertex != -1 && m_shape.IsEqualXY(vertex, cluster_pt)); bool b_continuing_segment_chain_optimization = swept_edges_to_delete.Size() == 1 && edges_to_insert.Size() == 2; int new_left = -1; int new_right = -1; // Process the cluster for (int i = 0, n = swept_edges_to_delete.Size(); i < n; i++) { // Find left and right neighbour of the edges that terminate at // the cluster (there will be atmost only one left and one // right). int edge = swept_edges_to_delete.Get(i); int left = m_sweep_structure.GetPrev(edge); if (left != -1 && !swept_edges_to_delete.HasElement(left)) { // Note: // for // some // heavy // cases, // it // could // be // better // to // use // binary // search. System.Diagnostics.Debug.Assert((new_left == -1)); new_left = left; } int right = m_sweep_structure.GetNext(edge); if (right != -1 && !swept_edges_to_delete.HasElement(right)) { System.Diagnostics.Debug.Assert((new_right == -1)); new_right = right; } //#ifdef NDEBUG if (new_left != -1 && new_right != -1) { break; } } //#endif System.Diagnostics.Debug.Assert((new_left == -1 || new_left != new_right)); m_sweep_comparator.SetSweepY(cluster_pt.y, cluster_pt.x); // Delete the edges that terminate at the cluster. for (int i_1 = 0, n = swept_edges_to_delete.Size(); i_1 < n; i_1++) { int edge = swept_edges_to_delete.Get(i_1); m_sweep_structure.DeleteNode(edge, -1); } swept_edges_to_delete.Clear(false); if (!b_continuing_segment_chain_optimization && new_left != -1 && new_right != -1) { if (CheckForIntersections_(new_left, new_right)) { b_needs_cracking = true; m_non_simple_result = m_sweep_comparator.GetResult(); break; } } for (int i_2 = 0, n = edges_to_insert.Size(); i_2 < n; i_2 += 2) { int v = edges_to_insert.Get(i_2); int otherv = edges_to_insert.Get(i_2 + 1); int new_edge_1 = -1; if (b_continuing_segment_chain_optimization) { new_edge_1 = m_sweep_structure.AddElementAtPosition(new_left, new_right, v, true, true, -1); b_continuing_segment_chain_optimization = false; } else { new_edge_1 = m_sweep_structure.AddElement(v, -1); } // the // sweep // structure // consist // of // the // origin // vertices // for // edges. // One // can // always // get // the // other // endpoint // as // the // next // vertex. if (m_sweep_comparator.IntersectionDetected()) { m_non_simple_result = m_sweep_comparator.GetResult(); b_needs_cracking = true; break; } int e_1 = m_shape.GetUserIndex(otherv, edge_index_1); if (e_1 == -1) { m_shape.SetUserIndex(otherv, edge_index_1, new_edge_1); } else { System.Diagnostics.Debug.Assert((m_shape.GetUserIndex(otherv, edge_index_2) == -1)); m_shape.SetUserIndex(otherv, edge_index_2, new_edge_1); } } if (b_needs_cracking) { break; } // Start accumulating new cluster edges_to_insert.ResizePreserveCapacity(0); } m_shape.RemoveUserIndex(edge_index_1); m_shape.RemoveUserIndex(edge_index_2); return(b_needs_cracking); }
protected internal virtual int CompareVertex_(com.epl.geometry.Treap treap, int node, int vertex) { bool bCurve = m_shape.GetSegment(vertex) != null; if (!bCurve) { m_shape.QueryLineConnector(vertex, m_line_1); m_env.SetCoordsNoNaN_(m_line_1.GetStartX(), m_line_1.GetEndX()); } if (bCurve) { throw new com.epl.geometry.GeometryException("not implemented"); } if (m_point_of_interest.x + m_tolerance < m_env.vmin) { return(-1); } if (m_point_of_interest.x - m_tolerance > m_env.vmax) { return(1); } if (m_line_1.GetStartY() == m_line_1.GetEndY()) { m_current_node = node; m_b_intersection_detected = true; return(0); } m_line_1.OrientBottomUp_(); com.epl.geometry.Point2D start = m_line_1.GetStartXY(); com.epl.geometry.Point2D vector = new com.epl.geometry.Point2D(); vector.Sub(m_line_1.GetEndXY(), start); vector.RightPerpendicular(); com.epl.geometry.Point2D v_2 = new com.epl.geometry.Point2D(); v_2.Sub(m_point_of_interest, start); double dot = vector.DotProduct(v_2); dot /= vector.Length(); if (dot < -m_tolerance * 10) { return(-1); } if (dot > m_tolerance * 10) { return(1); } if (m_line_1.IsIntersecting(m_point_of_interest, m_tolerance)) { double absDot = System.Math.Abs(dot); if (absDot < m_min_dist) { m_current_node = node; m_min_dist = absDot; } m_b_intersection_detected = true; if (absDot < 0.25 * m_tolerance) { return(0); } } return(dot < 0 ? -1 : 1); }
// Compares the moniker, contained in the Moniker_comparator with the // element contained in the given node. internal override int Compare(com.epl.geometry.Treap treap, int node) { int vertex = treap.GetElement(node); return(CompareVertex_(treap, node, vertex)); }
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)); }
// Compares the moniker, contained in the MonikerComparator with the // element contained in the given node. internal abstract int Compare(com.epl.geometry.Treap treap, int node);