Class RuppertRefiner
- java.lang.Object
-
- org.tinfour.refinement.RuppertRefiner
-
- All Implemented Interfaces:
IDelaunayRefiner
public class RuppertRefiner extends Object implements IDelaunayRefiner
RuppertRefiner implements Ruppert’s Delaunay refinement for improving mesh quality of anIIncrementalTin.The refiner iteratively refines poor-quality triangles by inserting Steiner points (Shewchuk-style off-centers with circumcenter fallback) and by splitting encroached constrained subsegments. Several practical safeguards are included to avoid pathological infinite refinement:
- radius-edge gating (configurable; optionally enforces ρ ≥ √2);
- concentric-shell segment tagging to enable robust off-center / midpoint handling;
- identification of seditious edges (midpoints on the same shell about a critical corner) and optional skipping/ignoring of these in split/encroachment decisions to prevent ping-pong cascades;
- scale-aware tolerances for encroachment, near-vertex and near-edge checks to avoid degenerate insertions.
Features and guarantees:
- The refiner is driven by a minimum-angle (or equivalently a circumradius-to-shortest-edge ratio) goal supplied at construction. When configured to enforce the √2 guard, the implementation follows standard termination theory (Ruppert/Shewchuk) and mitigates many non-adversarial inputs.
- Concentric-shell and seditious-edge logic extend robustness to small corner cases commonly observed in practice.
- By default the algorithm uses off-center insertion (Shewchuk) and splits constrained segments when required by encroachment rules.
- Terminated either when no encroached subsegments and no poor triangles remain, or when an iteration cap is reached.
References:
- J. Ruppert, "A Delaunay Refinement Algorithm for Quality 2-Dimensional Mesh Generation", J. Algorithms (1995).
- J. R. Shewchuk, "Delaunay Refinement Mesh Generation", 1997.
- Author:
- Michael Carleton
-
-
Constructor Summary
Constructors Constructor Description RuppertRefiner(IIncrementalTin tin, double minAngleDeg)Constructs a RuppertRefiner with the requested minimum internal triangle angle.RuppertRefiner(IIncrementalTin tin, double minAngleDeg, double minTriangleArea)Constructs a RuppertRefiner with the requested minimum internal triangle angle and a user-specified minimum triangle area threshold.RuppertRefiner(IIncrementalTin tin, double minAngleDeg, double minTriangleArea, boolean enforceSqrt2Guard, boolean skipSeditiousTriangles, boolean ignoreSeditiousEncroachments)Constructs a RuppertRefiner with explicit runtime policy options.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static RuppertRefinerfromEdgeRatio(IIncrementalTin tin, double ratio)Creates a RuppertRefiner configured by a target circumradius-to-shortest-edge ratioratio.booleanrefine()Perform refinement on the suppliedIIncrementalTin.VertexrefineOnce()Performs a single refinement operation on the associated triangulation.
-
-
-
Constructor Detail
-
RuppertRefiner
public RuppertRefiner(IIncrementalTin tin, double minAngleDeg)
Constructs a RuppertRefiner with the requested minimum internal triangle angle.The refiner will try to remove triangles with angles smaller than
minAngleDeg. The implementation uses off-center insertion with circumcenter fallback, encroachment checks for constrained subsegments, and several practical safeguards (concentric-shell tagging and seditious-edge handling) to prevent pathological infinite refinement loops.Parameters and preconditions:
tinmust be non-null and bootstrapped (already built).minAngleDegmust be in (0, 60) degrees; values near the theoretical limits may still fail to terminate.
- Parameters:
tin- the incremental triangulation to refine (non-null, bootstrapped)minAngleDeg- the requested minimum angle in degrees (0 < θ < 60)- Throws:
IllegalArgumentException- on invalid inputs
-
RuppertRefiner
public RuppertRefiner(IIncrementalTin tin, double minAngleDeg, double minTriangleArea)
Constructs a RuppertRefiner with the requested minimum internal triangle angle and a user-specified minimum triangle area threshold.The
minTriangleAreais used as a conservative safeguard to avoid attempting to refine triangles whose area is extremely small (in the coordinate units squared). A value of 0 disables the area-based skipping.- Parameters:
tin- the incremental triangulation to refine (non-null, bootstrapped)minAngleDeg- the requested minimum angle in degrees (0 < θ < 60)minTriangleArea- area threshold for skipping refinement of very small triangles (must be ≥ 0)- Throws:
IllegalArgumentException- on invalid inputs
-
RuppertRefiner
public RuppertRefiner(IIncrementalTin tin, double minAngleDeg, double minTriangleArea, boolean enforceSqrt2Guard, boolean skipSeditiousTriangles, boolean ignoreSeditiousEncroachments)
Constructs a RuppertRefiner with explicit runtime policy options.This overload exposes three boolean options useful for production tuning:
enforceSqrt2Guard— whentrue, the internal radius-edge gating enforcesρ ≥ √2(Shewchuk/Ruppert termination guard).skipSeditiousTriangles— whentrue, triangles whose shortest edges have been marked seditious are not attempted for split.ignoreSeditiousEncroachments— whentrue, encroachments identified as seditious are ignored (prevents ping-pong splitting).
- Parameters:
tin- the incremental triangulation to refine (non-null, bootstrapped)minAngleDeg- the requested minimum angle in degrees (0 < θ < 60)minTriangleArea- area threshold for skipping very small triangles (must be ≥ 0)enforceSqrt2Guard- whether to force the ρ ≥ √2 termination guardskipSeditiousTriangles- whether to skip splitting triangles whose shortest edges are seditiousignoreSeditiousEncroachments- whether to ignore seditious encroachments- Throws:
IllegalArgumentException- on invalid inputs
-
-
Method Detail
-
fromEdgeRatio
public static RuppertRefiner fromEdgeRatio(IIncrementalTin tin, double ratio)
Creates a RuppertRefiner configured by a target circumradius-to-shortest-edge ratioratio.This factory computes the equivalent minimum angle from
ratio(viaθ = arcsin(1/(2·ratio))) and delegates to the primary constructor. The created refiner will attempt to eliminate triangles whose circumradius-to-shortest-edge ratio meets or exceeds the implied target.- Parameters:
tin- the incremental TIN to refine; must be bootstrapped and non-nullratio- the target circumradius-to-shortest-edge ratio (must be > 0)- Returns:
- a configured
RuppertRefiner - Throws:
IllegalArgumentException- iftinis null or not bootstrapped, or ifratio <= 0
-
refine
public boolean refine()
Perform refinement on the suppliedIIncrementalTin.This method runs Ruppert’s iterative loop:
- collect constrained segments;
- split an encroached constrained segment if any;
- otherwise find a largest bad triangle and attempt an off-center insert (circumcenter fallback) or split an encroached segment found while testing the candidate;
- repeat until no encroached segments and no bad triangles remain or an iteration cap is reached.
The method is re-entrant in the sense it mutates the supplied
tin; it returns true when refinement converges or false if the maximum iteration cap is hit.- Specified by:
refinein interfaceIDelaunayRefiner- Returns:
trueif the refinement process terminated successfully because the triangulation meets the configured quality criteria;falseif the process terminated early due to a hard iteration cap or other imposed stopping condition before the criteria were satisfied.
-
refineOnce
public Vertex refineOnce()
Description copied from interface:IDelaunayRefinerPerforms a single refinement operation on the associated triangulation.Implementations should perform one atomic refinement step: identify an element that violates the configured quality criteria (for example a "bad" triangle) and repair it (for example by inserting a Steiner vertex, performing local retriangulation or edge flips). This method mutates the underlying triangulation in-place.
Implementation Note: Implementations are encouraged to make this method behave predictably when invoked repeatedly: calling it repeatedly on an unchanged triangulation should either return the same inserted vertex until the local repair completes, or return
nullonce no further single-step refinements are required.- Specified by:
refineOncein interfaceIDelaunayRefiner- Returns:
- the
Vertexthat was inserted as part of this refinement step, ornullif no refinement was necessary (the triangulation already meets the quality criteria or no applicable operation was available). - See Also:
IDelaunayRefiner.refine()
-
-