Delaunay Refinement Grid Generation Øyvind Hjelle oyvindhj@simula.no, +47 67 82 82 75 Simula Research Laboratory, www.simula.no October 19, 2009 Motivation Meshing for the Finite Element Method (FEM) Good triangulations for surface modelling with constraints A general means to compensate for “ill-conditioned” behaviour of CDTs Also called meshing or gridding We still operate in R2 (Delaunay and Constrained Delaunay) Some of the figures in this slide set is from Jonathan Shewchuk, see lecture notes. FEM (Finite Element Method) Triangulations as a basis for solving partial differential equations numerically. Differential equations, for example representing heat distribution or airflow, are approximated with piecewise polynomial functions over a finite element mesh and solved numerically to achieve an approximate solution of the original problem. FEM meshes have typically complicated exterior and interior boundaries (holes) and linear features: Thus: CDTs (Constrained Delaunay Triangulations)! The Refinement Process (very briefly) Input: A PSLG G (Planar straight line graph) 1 Make the initial CDT of G Loop (refinement): 2 Split long edges (constraints) 3 “Kill” skinny triangles The triangulation is always maintained as a CDT The basic operation is insertNode (into the CDT) Preview of algorithm Algorithm (Delaunay Refinement Grid Generation) 1 Make the initial CDT of the PSLG. Remove triangles outside the triangulation domain. 2 while skinny triangles remain 3 while any segment s is encroached upon SplitSegment(s) 4 5 Let t be a skinny triangle and v its circumcenter. 6 If v encroaches upon any segments s1 , s2 , . . . , sk for i = 1, . . . , k 7 SplitSegment(sk) 8 goto 3 9 10 else 11 KillTriangle(t) 12 goto 5 A sample input PSLG. Constrained Delaunay triangulation of the PSLG. Encroached segments are bold. One encroached segment is bisected. And another. A third encroached subsegment is split. The last encroached subsegment is split. Find a skinny triangle. The skinny triangle’s cirumcenter is inserted. Find another skinny triangle. This cirumcent croaches upon a and is rejected. Although the vertex was rejected, the segment it encroached upon is still marked for bisection. The encroached segment is split, and the skinny triangle that led to its bisection is eliminated. A circumcenter is successfully inserted, creating another skinny triangle. The triangle’s cir ter is rejected. The encroached subsegment will be split. The skinny triangle was not eliminated. Attempt to insert its circumcenter again. This time, its circumcenter is inserted successfully. There’s only one skinny triangle left. The final mesh. N is smaller than 20 Examples Requirements for FEM Meshes Triangle size Not too small: size of equation system (and CPU-time) is linear in the number of triangles. Sufficiently dense: Accuracy of the solution increases with increasing density of triangles. Solution: Adaptive mesh with good grading. Triangle shape Skinny triangles give numerical unstability: ill-conditioned equation systems in FEM problems numerical unstability in interpolation with polynomials (splines) defined over triangles ↓ Recall the Delaunay property ↓ Delaunay Refinement Node Insertion Node insertions should “kill” triangles with poor quality! Fundamental questions 1 What exactly is a well-shaped triangle or a triangle with poor quality? 2 Where should the next node be inserted during the refinement process? 3 Will the refinement procedure terminate? 4 Can we control/guarantee good spatial grading? Circumradius-to-shortest-edge ratio r/l 10 9 8 αmin αmin r 7 6 5 r/l 4 3 2 1 0 l 5 10 15 20 25 30 αmin 35 40 45 50 55 60 Relationship between αmin and r/l. Definition (Circumradius-to-shortest-edge ratio r/l) Ratio between radius r of the circumcircle of a triangle, and the length of its shortest edge l. The smallest angle is always opposite to the shortest edge. Equivalent with smallest angle measure: r 1 = . l 2 sin αmin minimizing r/l corresponds to maximizing αmin . Example: The equilateral triangle with angles 60◦ obtains the largest possible αmin and the smallest r/l. 1 1 r = = √ ≈ 0.58. ◦ l 2 sin 60 3 Also used in the literature is aspect ratio of a triangle: Ratio between length of the longest edge and the shortest altitude. Bounds the minimum angle αmin of a the triangle as, 2 1 ≤ Aspect ratio ≤ , sin αmin sin αmin (Aspect ratio is not used further.) Upper bound B on the circumradius-to-shortest-edge ratio r/l Delaunay refinement algorithms operate with an upper bound B on the circumradius-to-shortest-edge ratio r/l; or equivalently, a lower bound on the minimum angle: 1 2B = 180◦ − 2 arcsin 1/2B) αmin = arcsin (αmax The notion of skinny triangle Any triangle with r/l ratio greater than a required upper bound B will be called skinny. Example with B = B(= max r/l) √1 2 √ 2 and B = 1: 1 αmin = arcsin 2B 30◦ ≈ 20.7◦ αmax = 180◦ − 2αmin 120◦ ≈ 138.6◦ Note: This is not possible to obtain if the input PSLG has angles smaller than αmin between incident segments. (segment = constrained edge) Where should the next node p be inserted in a CDT ∆? Temporary assumption: We first assume that ∆ has no constraints. Let t be a skinny triangle (with r/l > B) and C(t) its circumcircle. Insertion of a new node inside C(t) kills t ! If p is inserted too close to any existing nodes we get dissatisfactory r/l ratio. ⇓ Insert p “as far from existing nodes as possible” ! ⇓ Insert p at the center of C(t) (equidistant from the three nodes of t.) Definition (Circumcenter) Circumcenter = center of C(t). Recall the definition of Voronoi diagram, and Delaunay triangulation as its dual construction: The circumcenter of t is at the Voronoi point where the Voronoi edges corresponding to t intersect. ⇓ The circumcenter of t is more distant from other nodes in ∆ than it is from the three nodes of t. Temporary assumption: Circumcenters of skinny triangles are inside ∆. Node insertion at circumcenters of skinny triangles: (b) (a) p t t (d) (c) p t p Kill skinny triangle t with r/l ≈ 2.14 > B Recall node insertion of p in a CDT: Connect p to all boundary nodes of the influence region Rp : Three of the new edges have length equal to the circumradius r of t, and the other new edges are longer than r. t was chosen because, r/l > B =⇒ new edges has length at least Bl. If B > 1 (αmin < 30◦ ), no new edges are shorter than the edges of t. (This will be used later when examining termination) We also obtain nice spatial grading from small to large triangles. Recall node insertion of p in a CDT: Connect p to all boundary nodes of the influence region Rp : Three of the new edges have length equal to the circumradius r of t, and the other new edges are longer than r. t was chosen because, r/l > B =⇒ new edges has length at least Bl. If B > 1 (αmin < 30◦ ), no new edges are shorter than the edges of t. (This will be used later when examining termination) We also obtain nice spatial grading from small to large triangles. Recall node insertion of p in a CDT: Connect p to all boundary nodes of the influence region Rp : Three of the new edges have length equal to the circumradius r of t, and the other new edges are longer than r. t was chosen because, r/l > B =⇒ new edges has length at least Bl. If B > 1 (αmin < 30◦ ), no new edges are shorter than the edges of t. (This will be used later when examining termination) We also obtain nice spatial grading from small to large triangles. Recall node insertion of p in a CDT: Connect p to all boundary nodes of the influence region Rp : Three of the new edges have length equal to the circumradius r of t, and the other new edges are longer than r. t was chosen because, r/l > B =⇒ new edges has length at least Bl. If B > 1 (αmin < 30◦ ), no new edges are shorter than the edges of t. (This will be used later when examining termination) We also obtain nice spatial grading from small to large triangles. A short summary before we proceed 10 9 8 αmin αmin r 7 6 5 r/l 4 3 2 1 0 l 5 10 15 20 25 30 αmin 35 40 45 50 55 60 Relationship between αmin and r/l. We want to “kill” all triangles with r/l ratio greater than the upper bound B Thus, all new edges have length at least Bl. Temporary assumptions: Circumcenters of skinny triangles are inside ∆. ∆ has no constrained edges. A curiosity: Suppose (temporarily) that a skinny triangle is one with: “circumradius greater than the shortest edge in the entire mesh”. ⇓ An upper bound r/l ≤ 1 would be achieved corresponding to αmin = 30◦ ; and The mesh will be uniform with all triangles approximately the same size (and more triangles); see the first mesh. Splitting Encroached Segments Recall temporary assumptions above: 1 No constraints 2 Circumcenters are inside ∆ Definition Segment = constrained edge. Edges of exterior and interior boundaries are segments. The input PSLG and ∆ are segment-bounded. Definition Subsegments = segments that have been split. Let s be a segment or subsegment of a CDT. Definition (Diametral circle) The diametral circle of s is the circle with s “as a diameter”. Definition (Encroachment) Segment s is encroached upon if a node different from the endpoints of s lies on or inside the diametral circle of s and the node is visible from the interior of s. (a) (b) (c) Splitting of an encroached segment. Rule for splitting: Eliminate all encroached segments in the CDT ∆. 1 Insert a new node at the midpoint of an encroached segment (or subsegment) s. 2 s is replaced by two new segments s1 and s2 . 3 Update ∆ to be Delaunay (see figure). Termination is not guaranteed! Endless loop if α ≤ 45◦ : p s2' ' 1 s × α s1 × q s2 α ≤ 45◦ New Assumption: (temporarily until corner-lopping in the end): α > 45◦ between incident segments in the input PSLG; (and no other configurations give endless loops.) But from now on: allow constrained edges! Lemma A triangle t in a segment-bounded Delaunay triangulation is never separated from its circumcenter v by a segment s if the segment is not encroached upon. Proof. By contradiction: Suppose that v is separated from t by a segment s that is not encroached upon; see figure. Let s be the ’closest’ segment to t that is not encroached upon. Let s′ be the part of s inside C(t) Because t is (constrained) Delaunay, both endpoints of s are outside C(t). Since v and t lie on opposite sides of s′ , the portion of C(t) on the same side of s′ as t lies inside C(s′ ). > At least one node of t must be strictly inside C(s′ ). >> But C(s′ ) is inside C(s), so then at least one of the nodes of t encroaches upon s! Contradiction!!! Lemma A triangle t in a segment-bounded Delaunay triangulation is never separated from its circumcenter v by a segment s if the segment is not encroached upon. Proof. By contradiction: Suppose that v is separated from t by a segment s that is not encroached upon; see figure. Let s be the ’closest’ segment to t that is not encroached upon. Let s′ be the part of s inside C(t) Because t is (constrained) Delaunay, both endpoints of s are outside C(t). Since v and t lie on opposite sides of s′ , the portion of C(t) on the same side of s′ as t lies inside C(s′ ). > At least one node of t must be strictly inside C(s′ ). >> But C(s′ ) is inside C(s), so then at least one of the nodes of t encroaches upon s! Contradiction!!! C (t ) C (s ' ) t v s' s Consequences of segment splitting: When all encroached segments have been split: 1 The visibility between v and t is never obscured by a segment. =⇒ t will always disappear when a node is inserted at v. 2 Recall: edges of the exterior boundary and interior boundaries enclosing holes are also segments =⇒ v never falls outside the triangulatation or inside holes where there are no triangles. Note: Only one assumption left: α > 45◦ between incident segments in the input PSLG. The Delaunay Refinement Algorithm Input: a segment-bounded PSLG. Two basic operations: SplitSegment(s): Insert a node at the midpoint of a segment s. KillTriangle(t): Insert a node at the circumcenter of a (skinny) triangle t. KillTriangle: Only applied when there are no encroached segments present in ∆. Both operations update ∆ to be constrained Delaunay. Algorithm (Delaunay Refinement Grid Generation) 1 Make the initial CDT of the PSLG. Remove triangles outside the triangulation domain. 2 while skinny triangles remain 3 while any segment s is encroached upon SplitSegment(s) 4 5 Let t be a skinny triangle and v its circumcenter. 6 If v encroaches upon any segments s1 , s2 , . . . , sk (“look-ahead”) for i = 1, . . . , k 7 SplitSegment(sk) 8 goto 3 9 10 else 11 KillTriangle(t) 12 goto 5 the algorithm... Step 9 goes to segment splitting again because: The skinny triangle t may disappear during segment splitting in Step 8 if one of its edges is swapped. New nodes used for segment splitting may encroach upon other segments. The result is not unique: depends on the order in which segments are split! the algorithm... Step 9 goes to segment splitting again because: The skinny triangle t may disappear during segment splitting in Step 8 if one of its edges is swapped. New nodes used for segment splitting may encroach upon other segments. The result is not unique: depends on the order in which segments are split! the algorithm... Step 9 goes to segment splitting again because: The skinny triangle t may disappear during segment splitting in Step 8 if one of its edges is swapped. New nodes used for segment splitting may encroach upon other segments. The result is not unique: depends on the order in which segments are split! the algorithm... Step 9 goes to segment splitting again because: The skinny triangle t may disappear during segment splitting in Step 8 if one of its edges is swapped. New nodes used for segment splitting may encroach upon other segments. The result is not unique: depends on the order in which segments are split! Termination of Algorithm The algorithm terminates when there are no encroached segments and no skinny triangles left. Is termination guaranteed? Why shouldn’t it terminate? Because both KillTriangle and SplitSegment may create new skinny triangles? ⇓ The algorithm may run forever creating more and more (and smaller and smaller) triangles and never get rid of all skinny triangles? Under what conditions will the algorithm terminate? Definition (Local Feature Size) Given a PSLG G. The local feature size at an arbitrary point p ∈ R2 relative to G, denoted lf sG (p) (or only lf s(p)) is the radius of the smallest disk centered at p that intersects two non-incident nodes or segments of G. Local feature size lf s() at × = radius of circle. lf s(·) is relative to G and never changed during refinement lf s(·) continuous lf s(p) > 0 for all points p Steepness in the range [−1, 1] in any direction: Definition (Local Feature Size) Given a PSLG G. The local feature size at an arbitrary point p ∈ R2 relative to G, denoted lf sG (p) (or only lf s(p)) is the radius of the smallest disk centered at p that intersects two non-incident nodes or segments of G. Local feature size lf s() at × = radius of circle. lf s(·) is relative to G and never changed during refinement lf s(·) continuous lf s(p) > 0 for all points p Steepness in the range [−1, 1] in any direction: Definition (Local Feature Size) Given a PSLG G. The local feature size at an arbitrary point p ∈ R2 relative to G, denoted lf sG (p) (or only lf s(p)) is the radius of the smallest disk centered at p that intersects two non-incident nodes or segments of G. Local feature size lf s() at × = radius of circle. lf s(·) is relative to G and never changed during refinement lf s(·) continuous lf s(p) > 0 for all points p Steepness in the range [−1, 1] in any direction: Definition (Local Feature Size) Given a PSLG G. The local feature size at an arbitrary point p ∈ R2 relative to G, denoted lf sG (p) (or only lf s(p)) is the radius of the smallest disk centered at p that intersects two non-incident nodes or segments of G. Local feature size lf s() at × = radius of circle. lf s(·) is relative to G and never changed during refinement lf s(·) continuous lf s(p) > 0 for all points p Steepness in the range [−1, 1] in any direction: Definition (Local Feature Size) Given a PSLG G. The local feature size at an arbitrary point p ∈ R2 relative to G, denoted lf sG (p) (or only lf s(p)) is the radius of the smallest disk centered at p that intersects two non-incident nodes or segments of G. Local feature size lf s() at × = radius of circle. lf s(·) is relative to G and never changed during refinement lf s(·) continuous lf s(p) > 0 for all points p Steepness in the range [−1, 1] in any direction: Lemma Given a PSLG and two points p and q in the plane. Then lf s(q) ≤ lf s(p) + d(p, q), where d(p, q) is the Euclidean distance between p and q. (This result is not used further.) Definition (Insertion radius) The insertion radius rv of an insertion node v is the length of the shortest Delaunay edge connected to v immediately after KillTriangle or SplitSegment has executed. And other cases: 1 If v is an input node of the PSLG: rv = length of shortest edge connected to v after the initial CDT has been constructed and before the refinement process starts. 2 If v is a rejected node (encroaches upon a segment): rv = shortest Delaunay edge connected to v as if v had been inserted. Recall the Delaunay property (figure, next slide): 1 New edges created when inserting v have v as a common endpoint. 2 The closest node visible from v defines the shortest edge connected to v. (b) (a) p t t (d) (c) p t p Example: Insertion radius of p is the ‘circumradius’ of t. termination, continued... First goal: Find lower bound on insertion radius rv in all possible cases of KillTriangle and SplitSegment. (That is, such that rv ≥ “something”) Definition (Parent node) The parent node p of an insertion node v is the node “responsible” for the insertion of v. (Explained under “cases” that follow.) (a) (b) Input PSLG t p p rv l ≥ rg g rp v rv v s (c) s (d) s’ s’ p p l a α β rv l a v α rv β s Encroachment cases. v s Cases for KillTriangle and SplitSegment: Different roles of the parent node p. Case 1. (KillTriangle(t)): p is the last inserted node of the two endpoints of the shortest edge of t. Case 2. (SplitSegment(s)): p is the nearest node that encroaches upon s. Facts: p lies inside C(s). The shortest edge connected to v, which define the insertion radius rv , has p as the other endpoint if p is in ∆ (, that is, if it was not rejected in Step 6). Four possible roles of parent node p: 2a. p is an input node, or p is a node inserted in a segment not incident with s. (Fig. (a)) 2b. p is at the circumcenter of a skinny triangle and thus rejected since it encroaches upon s. (Fig. (b), and Step 6–8). 2c. p is a node on a segment s′ incident with s that makes an angle 45◦ ≤ α < 90◦ with s. (Fig. (c)). 2d. p is a node on a segment s′ incident with s that makes an angle α ≤ 45◦ with s. (Fig. (d)) Cases for KillTriangle and SplitSegment: Different roles of the parent node p. Case 1. (KillTriangle(t)): p is the last inserted node of the two endpoints of the shortest edge of t. Case 2. (SplitSegment(s)): p is the nearest node that encroaches upon s. Facts: p lies inside C(s). The shortest edge connected to v, which define the insertion radius rv , has p as the other endpoint if p is in ∆ (, that is, if it was not rejected in Step 6). Four possible roles of parent node p: 2a. p is an input node, or p is a node inserted in a segment not incident with s. (Fig. (a)) 2b. p is at the circumcenter of a skinny triangle and thus rejected since it encroaches upon s. (Fig. (b), and Step 6–8). 2c. p is a node on a segment s′ incident with s that makes an angle 45◦ ≤ α < 90◦ with s. (Fig. (c)). 2d. p is a node on a segment s′ incident with s that makes an angle α ≤ 45◦ with s. (Fig. (d)) Cases for KillTriangle and SplitSegment: Different roles of the parent node p. Case 1. (KillTriangle(t)): p is the last inserted node of the two endpoints of the shortest edge of t. Case 2. (SplitSegment(s)): p is the nearest node that encroaches upon s. Facts: p lies inside C(s). The shortest edge connected to v, which define the insertion radius rv , has p as the other endpoint if p is in ∆ (, that is, if it was not rejected in Step 6). Four possible roles of parent node p: 2a. p is an input node, or p is a node inserted in a segment not incident with s. (Fig. (a)) 2b. p is at the circumcenter of a skinny triangle and thus rejected since it encroaches upon s. (Fig. (b), and Step 6–8). 2c. p is a node on a segment s′ incident with s that makes an angle 45◦ ≤ α < 90◦ with s. (Fig. (c)). 2d. p is a node on a segment s′ incident with s that makes an angle α ≤ 45◦ with s. (Fig. (d)) (a) (b) Input PSLG t p p rv l ≥ rg g rp v rv v s (c) s (d) s’ s’ p p l a α β rv l a v α rv β v s s Encroachment cases. Lemma The insertion radius rv has the following lower bounds: Case 1. rv ≥ Brp , Case 2a. rv ≥ lf s(v), √ Case 2b. rv ≥ rp / 2, Case 2c. rv ≥ rp /(2 cos α), Case 2d. rv ≥ rp sin α. Proof. rv v t l p Case 1. KillTriangle(t) - case. Recall: t was chosen because r/l > B. ⇒ new edges has length at least Bl. Facts: i) shortest new edge has length rv (by definition) ii) l ≥ rp =⇒ rv ≥ Brp . proof... (a) Input PSLG p rv v s Case 2a. Consult Figure (a). Follows directly from definition of local feature size: rv ≥ lf s(v). proof... (b) (e) t p g p rp rp rv l ≥ rg t l ≥ rg g rv v s v s Case 2b. Consult Figure (b). > p is rejected, so rv = |s| /2. > rp = circumradius of t. > Lower bound on rv in terms of rp is achieved when rv /rp is minimized under the constraint that p lies on or inside C(s). > The Delaunay property ensures that C(t) cannot contain endpoints of s. Figure (e) illustrates the position of p and C(t) for √ 2. min rv /rp = 1/ √ =⇒ rv ≥ rp / 2. proof... s’ (c) p l a α β rv v s Case 2c. Consult Figure (c). l ≥ rp . rv equals length of vp. Law of sines gives, rv /l = sin α/ sin β. Let α be fixed. Since l ≥ rp , a lower bound on rv is achieved by minimizing rv /l under the constraint that p lies on or inside C(s). α ≥ 45◦ =⇒ β ≤ 90◦ =⇒ sin β ≤ 1. =⇒ min rv /l when β is maximum under the given constraint. =⇒ When p lies on C(s), which gives rv = l/(2 cos α). =⇒ rv ≥ rp /(2 cos α). proof... (d) s’ p l a α rv β v s α ≤ 45◦ Case 2d. Consult Figure (d). Use the same analysis as in Case 2c; law of sines, sin α rv = . l sin β But now β is not bounded by 90◦ . =⇒ rv /l is minimized when sin β = 1, i.e., β = 90◦ . =⇒ rv = l sin α, and since l ≥ rp rv ≥ rp sin α. Goal: Each node insertion should generate edges that are either longer than an existing edge, or longer than a fixed feature in the PSLG. (to avoid chains of shorter and shorter edges and thus endless loops) Recall Case Case Case Case Case Lemma: 1. rv 2a. rv 2b. rv 2c. rv 2d. rv ≥ Brp , ≥ lf s(v), √ ≥ rp / 2, ≥ rp /(2 cos α), ≥ rp sin α. Case 2d: rv ≥ rp sin α for α ≤ 45. Recall that α < 45◦ generates an endless loop with SplitSegment in Step 3 and 4 of the Algorithm. Impossible to get rv ≥ rp . Case 2c: rv ≥ rp /(2 cos α) for 45◦ ≤ α < 90◦ rv ≥ rp if α ≥ 60◦ . (e) l ≥ rg t g p rp rv v s √ Case 2b: rv ≥ rp / 2. Note that node p was not inserted (rejected); the “look-ahead” in Algorithm! Case 1 defines a lower√bound for p√as rp ≥ Brg ; see figure. Combines to rv ≥ r√ p / 2 ≥ Brg / 2. rv ≥ rg when B ≥ 2. ... this also holds for Case√1: rv ≥ Brp . B ≥ 2 from Case 2b sufficient for rv ≥ rp . p (a) Input PSLG rv v s Case 2a: rv ≥ lf s(v), that is, the input PSLG bounds (determines) the the shortest edge connected to v! Further, rv ≥ min lf sG (·) over the entire domain. But, since v and p are non-incident: Let dmin be the shortest distance between two non-incident entities of the input PSLG. Then for any node v inserted by Algorithm, rv ≥ dmin dmin ≥ min lf sG (·), and thus a better bound! The same bound is (of course) valid for edges of the input PSLG. ⇓ No edge in the final mesh can be shorter than dmin ! WHY? Because: Case 2a, with rv ≥ dmin , is the only case that bounds rv (the shortest edge) in terms of the input PSLG, and: all the other cases have bounds at least rv ≥ rp , where p is either a previous inserted node, or. a node of the input PSLG. “Track the history back in time” from an insertion node v to its parent, grandparent, etc. and you will find that rv ≥ dmin represents a “last barricade” that bounds the shortest edge in the final mesh. ⇓ No edge in the final mesh can be shorter than dmin ! Summary so far: 1 Ever-decreasing edges cannot occur if: ◦ α ≥ 60 √ between incident segments of the input PSLG, and B ≥ 2. 2 dmin is a lower bound on the shortest edge in the final mesh. Is this sufficient for termination of Algorithm? YES, because: Every edge is Delaunay (in a CDT): > The shortest edge connected to v has the closest node visible from v as its other endpoint. >> A new node can never be inserted closer to an existing node than dmin , unless the visibility is obscured by a segment. Draw circles with radius dmin around each new node. Each such circle is node-free. Sooner or later there is no space left to draw circles. =⇒ TERMINATION. Theorem Let dmin be the shortest distance between two nonincident entities (nodes or segments) in the input PSLG. Let a triangle be considered skinny if its √circum-radius-to-shortest-edge ratio r/l > B, where B ≥ 2; and suppose that the angle between two incidents segments in the input PSLG is at least 60◦ Then the Algorithm terminates with no edge shorter than dmin , and arcsin 1 1 ≤ α ≤ 180◦ − 2 arcsin 2B 2B (≈ 20.7◦ ) ≤ α ≤ (≈ 138.6◦ ) αmin αmin r l We can handle the 60◦ restriction with “corner-lopping”: Corner-Lopping for Handling Small Input Angles Illustration from Shewchuk. 1 Lop off corners with sharp angles in the input PSLG G and obtain G′ with angles ≥ 60◦ . Lopping-circles with radius, e.g., r = lf sG (a)/3. 2 Run Algorithm on G′ 3 Fill in lopped off corners again. (see lecture notes for details) Examples Illustration from Ruppert. Illustration from Ruppert