double angle = angle(node.point, node.next.point, node.prev.point);
while( node.hasNext() ) if( isLargeHole(node) ) fill( tcx, node ); node = node.next; while( node.hasPrevious() ) if( isLargeHole(node) ) fill( tcx, node ); node = node.prev; angle = basinAngle( n ); if( angle < PI_3div4 ) fillBasin( tcx, n );
private static void fillEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { if( tcx.edgeEvent.right ) { fillRightAboveEdgeEvent( tcx, edge, node ); } else { fillLeftAboveEdgeEvent( tcx, edge, node ); } }
private static void fillRightConcaveEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { fill( tcx, node.next ); if( node.next.point != edge.p ) { // Next above or below edge? if( orient2d( edge.q, node.next.point, edge.p ) == Orientation.CCW ) { // Below if( orient2d( node.point, node.next.point, node.next.next.point ) == Orientation.CCW ) { // Next is concave fillRightConcaveEdgeEvent( tcx, edge, node ); } else { // Next is convex } } } }
private static void fillLeftConcaveEdgeEvent( DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node ) { fill( tcx, node.prev ); if( node.prev.point != edge.p ) { // Next above or below edge? if( orient2d( edge.q, node.prev.point, edge.p ) == Orientation.CW ) { // Below if( orient2d( node.point, node.prev.point, node.prev.prev.point ) == Orientation.CW ) { // Next is concave fillLeftConcaveEdgeEvent( tcx, edge, node ); } else { // Next is convex } } } }
rotateTrianglePair( t, p, ot, op ); tcx.mapTriangleToNodes( t ); tcx.mapTriangleToNodes( ot ); t.markConstrainedEdge( ep, eq ); ot.markConstrainedEdge( ep, eq ); legalize( tcx, t ); legalize( tcx, ot ); t = nextFlipTriangle( tcx, o, t, ot, p, op ); flipEdgeEvent( tcx, ep, eq, t, p ); newP = nextFlipPoint( ep, eq, ot, op ); flipScanEdgeEvent( tcx, ep, eq, t, ot, newP ); edgeEvent( tcx, ep, eq, t, p );
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 ); } } }
if( isShallow( tcx, node) ) fill( tcx, node ); if( node.prev == tcx.basin.leftNode && node.next == tcx.basin.rightNode ) fillBasinReq( tcx, node );
if( isEdgeSideOfTriangle( node.triangle, edge.p, edge.q ) ) fillEdgeEvent( tcx, edge, node ); edgeEvent( tcx, edge.p, edge.q , node.triangle, edge.q );
/** * 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( isEdgeSideOfTriangle( triangle, ep, eq ) ) edgeEvent( tcx, ep, p1, triangle, p1 ); edgeEvent( tcx, ep, p2, triangle, p2 ); edgeEvent( tcx, ep, eq, triangle, point ); flipEdgeEvent( tcx, ep, eq, triangle, point );
/** * 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 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.basin.leftHighest = tcx.basin.leftNode.getPoint().getY() > tcx.basin.rightNode.getPoint().getY(); fillBasinReq( tcx, tcx.basin.bottomNode );