private IndexNode<A> createIndex( int n ) { IndexNode<A> node = null; if( n > 0 ) { node = new IndexNode<A>(); node.bigger = createIndex( n-1 ); node.smaller = createIndex( n-1 ); } return node; }
public AdvancingFrontIndex( double min, double max, int depth ) { if( depth > 5 ) depth = 5; _root = createIndex( depth ); }
private static void fillEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { if( tcx.edgeEvent.right ) { fillRightAboveEdgeEvent( tcx, edge, node ); } else { fillLeftAboveEdgeEvent( tcx, edge, node ); } }
/** * Find closes node to the left of the new point and * create a new triangle. If needed new holes and basins * will be filled to. * * @param tcx * @param point * @return */ private static AdvancingFrontNode pointEvent( DTSweepContext tcx, TriangulationPoint point ) { AdvancingFrontNode node,newNode; node = tcx.locateNode( point ); if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( node ); } newNode = newFrontTriangle( tcx, point, node ); // Only need to check +epsilon since point never have smaller // x value than node due to how we fetch nodes from the front if( point.getX() <= node.point.getX() + EPSILON ) { fill( tcx, node ); } tcx.addNode( newNode ); fillAdvancingFront( tcx, newNode ); return newNode; }
tcx.addToList( triangle ); newNode = new AdvancingFrontNode( point ); newNode.next = node.next; newNode.prev = node; node.next = newNode; tcx.addNode( newNode ); // XXX: BST if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( newNode ); } if( !legalize( tcx, triangle ) ) tcx.mapTriangleToNodes( triangle );
/** Triangulate simple polygon with holes **/ public static void triangulate( DTSweepContext tcx ) { tcx.createAdvancingFront(); sweep( tcx ); if( tcx.getTriangulationMode() == TriangulationMode.POLYGON ) { finalizationPolygon( tcx ); } else { finalizationConvexHull( tcx ); } tcx.done(); }
private static void fillLeftBelowEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( node ); } if( node.point.getX() > edge.p.getX() ) { if( orient2d( node.point, node.prev.point, node.prev.prev.point ) == Orientation.CW ) { // Concave fillLeftConcaveEdgeEvent( tcx, edge, node ); } else { // Convex fillLeftConvexEdgeEvent( tcx, edge, node ); // Retry this one fillLeftBelowEdgeEvent( tcx, edge, node ); } } }
private static void fillRightAboveEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { while( node.next.point.getX() < edge.p.getX() ) { if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( node ); } // Check if next node is below the edge Orientation o1 = orient2d( edge.q, node.next.point, edge.p ); if( o1 == Orientation.CCW ) { fillRightBelowEdgeEvent( tcx, edge, node ); } else { node = node.next; } } }
private static void fillLeftAboveEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { while( node.prev.point.getX() > edge.p.getX() ) { if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( node ); } // Check if next node is below the edge Orientation o1 = orient2d( edge.q, node.prev.point, edge.p ); if( o1 == Orientation.CW ) { fillLeftBelowEdgeEvent( tcx, edge, node ); } else { node = node.prev; } } }
public void addNode( AdvancingFrontNode node ) { // System.out.println( "add:" + node.key + ":" + System.identityHashCode(node.key)); // m_nodeTree.put( node.getKey(), node ); aFront.addNode( node ); }
public AdvancingFrontNode locateNode( TriangulationPoint point ) { return aFront.locateNode( point ); }
public DTSweepContext() { clear(); }
@Override public TriangulationConstraint newConstraint( TriangulationPoint a, TriangulationPoint b ) { return new DTSweepConstraint( a, b ); }
public void removeNode( AdvancingFrontNode node ) { // System.out.println( "remove:" + node.key + ":" + System.identityHashCode(node.key)); // m_nodeTree.delete( node.getKey() ); aFront.removeNode( node ); }
public static TriangulationContext<?> createContext( TriangulationAlgorithm algorithm ) { switch( algorithm ) { case DTSweep: default: return new DTSweepContext(); } }
public void isDebugEnabled( boolean b ) { if( b ) { if( _debug == null ) { _debug = new DTSweepDebugContext(this); } } _debugEnabled = b; }
public static void triangulate( TriangulationContext<?> tcx ) { switch( tcx.algorithm() ) { case DTSweep: default: DTSweep.triangulate( (DTSweepContext)tcx ); } }
private static void finalizationPolygon( DTSweepContext tcx ) { // Get an Internal triangle to start with DelaunayTriangle t = tcx.aFront.head.next.triangle; TriangulationPoint p = tcx.aFront.head.next.point; while( !t.getConstrainedEdgeCW( p ) ) { t = t.neighborCCW( p ); } // Collect interior triangles constrained by edges tcx.meshClean( t ); }
/** * We use a balancing tree to locate a node smaller or equal to * given key value * * @param x * @return */ public AdvancingFrontNode locateNode( TriangulationPoint point ) { return locateNode( point.getX() ); }