locationtech / jts

The JTS Topology Suite is a Java library for creating and manipulating vector geometry.
Other
1.94k stars 442 forks source link

OffsetCurve has artifacts when Quadrant Segments is small #980

Closed dr-jts closed 1 year ago

dr-jts commented 1 year ago

From the issue in https://github.com/qgis/QGIS/issues/53165 it appears that using Quadrant Segments = 0 (or any small value) causes artifacts to appear. The QuadrantSegments value should be forced to be >= 8 when building offset curves. (Even better would be an ability to specify the End Cap Quadrant Segments independently of the Join QS).

The cause of the problem is that an end cap generated using a small QS value can expose "closing arc" linework at internal corners. This is a problem with generating buffers as well.

It also might be possible to detect and remove unwanted end cap segments when the QuadrantSegments value is small (at the ends of the offset curve, via a distance check).

Work-Around

Specify the Quadrant Segments value to be at least 8

Example 1

Input:

LINESTRING (553772.0645892698 177770.05079236583, 553780.9235869241 177768.99614978794, 553781.8325485934 177768.41771963477)

Offset Curve ( Distance = -11, QuadSegs = 0, Join = Mitre) :

LINESTRING (553770.7642474822 177759.1279213497, 553779.6232451365 177758.0732787718, 553779.8538176146 177760.0100875886)
image

With QuadSegs = 8 result is reasonable:

LINESTRING (553770.7642474822 177759.1279213497, 553777.5392247156 177758.32137644096)
image

Example 2 - from https://github.com/qgis/QGIS/issues/53165#issuecomment-1563214857

Input:

LINESTRING (417.9785426266025752 432.5653800140134990, 447.6161954912822694 436.0936720217578113, 450.6571140550076962 438.0288020166335627)

Offset Curve ( Distance = 133, QuadSegs = 0, Join = Mitre) :

MULTILINESTRING ((402.2562282849878 564.6328204819179, 431.8938811496675 568.1611124896622, 435.5163051787518 537.7327506457365), (382.10659133507295 539.037335707624, 376.21175503542906 548.3006498938425, 379.2526735991545 550.2357798887183))
image

With QuadSegs = 8 result is reasonable:

LINESTRING (402.2562282849878 564.6328204819179, 419.09117017340793 566.6369802305645)
image