/** * Start sweeping the Y-sorted point set from bottom to top * * @param tcx */ private static void sweep( DTSweepContext tcx ) { List<TriangulationPoint> points; TriangulationPoint point; AdvancingFrontNode node; points = tcx.getPoints(); for( int i=1; i<points.size(); i++ ) { point = points.get(i); node = pointEvent( tcx, point ); if( point.hasEdges() ) { for( DTSweepConstraint e : point.getEdges() ) { if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveConstraint( e ); } edgeEvent( tcx, e, node ); } } tcx.update( null ); } }
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; } } }
tcx.getDebugContext().setPrimaryTriangle( t ); tcx.getDebugContext().setSecondaryTriangle( ot );
tcx.edgeEvent.right = edge.p.getX() > edge.q.getX(); if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setPrimaryTriangle( node.triangle ); }
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 fillRightBelowEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( node ); } if( node.point.getX() < edge.p.getX() ) // needed? { if( orient2d( node.point, node.next.point, node.next.next.point ) == Orientation.CCW ) { // Concave fillRightConcaveEdgeEvent( tcx, edge, node ); } else { // Convex fillRightConvexEdgeEvent( tcx, edge, node ); // Retry this one fillRightBelowEdgeEvent( tcx, edge, node ); } } }
while( c != tcx.aFront.tail ) if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( c ); }
tcx.getDebugContext().setPrimaryTriangle( t ); tcx.getDebugContext().setSecondaryTriangle( ot );
/** * 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; }
if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setActiveNode( newNode ); }
if( tcx.isDebugEnabled() ) { tcx.getDebugContext().setPrimaryTriangle( triangle ); }