diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a738ce89..64eda6201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed 🐛 * It is now possible to click widgets even when FPS is very low. +* Tessellator: handle sharp path corners better (switch to bevel instead of miter joints for > 90°). ## 0.8.0 - 2021-01-17 - Grid layout & new visual style diff --git a/epaint/src/tessellator.rs b/epaint/src/tessellator.rs index 986a98a43..b7e25e42b 100644 --- a/epaint/src/tessellator.rs +++ b/epaint/src/tessellator.rs @@ -87,9 +87,21 @@ impl Path { n1 = n0; } - let v = (n0 + n1) / 2.0; - let normal = v / v.length_sq(); // TODO: handle VERY sharp turns better - self.add_point(points[i], normal); + let normal = (n0 + n1) / 2.0; + let length_sq = normal.length_sq(); + let right_angle_length_sq = 0.5; + let sharper_than_a_right_angle = length_sq < right_angle_length_sq; + if sharper_than_a_right_angle { + // cut off the sharp corner + let center_normal = normal.normalized(); + let n0c = (n0 + center_normal) / 2.0; + let n1c = (n1 + center_normal) / 2.0; + self.add_point(points[i], n0c / n0c.length_sq()); + self.add_point(points[i], n1c / n1c.length_sq()); + } else { + // miter join + self.add_point(points[i], normal / length_sq); + } } self.add_point( points[n - 1], @@ -115,12 +127,21 @@ impl Path { n1 = n0; } - // if n1 == Vec2::zero() { - // continue - // } - let v = (n0 + n1) / 2.0; - let normal = v / v.length_sq(); // TODO: handle VERY sharp turns better - self.add_point(points[i], normal); + let normal = (n0 + n1) / 2.0; + let length_sq = normal.length_sq(); + let right_angle_length_sq = 0.5; + let sharper_than_a_right_angle = length_sq < right_angle_length_sq; + if sharper_than_a_right_angle { + // cut off the sharp corner + let center_normal = normal.normalized(); + let n0c = (n0 + center_normal) / 2.0; + let n1c = (n1 + center_normal) / 2.0; + self.add_point(points[i], n0c / n0c.length_sq()); + self.add_point(points[i], n1c / n1c.length_sq()); + } else { + // miter join + self.add_point(points[i], normal / length_sq); + } } } }