SVGLoader: Improve round rect corners approximation #22132
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello!
The current approximation of SVG round rects with Bezier curves is too rough when corner radii are large enough and comparable to the dimensions. Here’s a simple Inkscape example where border-radius is almost ½ of the rect height:
round-rect.svg.zip
It renders in a browser like this:
And loads by THREE.js like this:
Note the curve “overruns”. I tried to follow the current algorithm on paper and it flaws in several ways:
2 * rx
and2 * ry
offsets is a mistake. They should not be doubled. That’s the reason for overrunI’ve adjusted the implementation and the rect now looks like:
BTW, is there any reason why
ShapePath
does not provide methods likearc
andellipse
? I see they can be trivially implemented as a proxy toPath
likelineTo
orbezierCurveTo
. It would allow avoiding approximation so that the corners may be implemented as true ellipse arcs. I suspect though there’s a reason, some dependency which does not allow to do it easily. Could you clarify this point? If it just “no time to bother”, I could try to do it.