Convert an SVG-path to polygons for use within Javascript Clipper

后端 未结 2 669
长情又很酷
长情又很酷 2020-12-30 16:38

I\'m trying to perform Boolean Operations on SVG Paths (that contain beziers, both quadratic and cubic) using JS Clipper.

JS Clipper starts with polygons then perfor

相关标签:
2条回答
  • 2020-12-30 17:32

    you can use De Casteljau's algorithm to break bezier curve into smaller straight lines, and join them to create polygon.

    Here is some references of De Casteljau's algorithm

    • http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html
    • http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html
    0 讨论(0)
  • 2020-12-30 17:35

    I assume that you mean some sort of svg path to polygon conversion.

    I have searched a lot, but not found anything reliable and out-of-the-box solution.

    SVG path can consist of ten different segment, or 20 if we take into account both relative and absolute coordinates. They are represented as letters in path element's d-attribute: relative ones are mhvlcqastz and absolute ones are MHVLCQASTZ. Each have different attributes, a (elliptical arc) being the most complicated one. The most usable and flexible of types is c (cubic bezier curve), because it can represent all other types in rather high precision as these examples show: http://jsbin.com/oqojan/32, http://jsbin.com/oqojan/42.

    Raphael JS library has Path2Curve-function which can convert all path segments to cubic curves and it can handle also the complicated arc to cubic conversion. Unfortunately it has a bug, so that it cannot handle all possible path segment combinations, but fortunately there is a fixed version of library available: http://jsbin.com/oqojan/32/edit (look at the Javascript-window).

    When all path segments are converted to cubic curves, they can be converted to individual line segments. There are few ways, and the best seems to be an adaptive recursive subdivision method, which produces more line segments in sharp turns of curve and fewer in other parts of curve to achieve a balance of curve fidelity and low count of segments to maximize rendering speed, but unfortunately it could not handle all collinear cases. I succeeded in converting AntiGrain's method to Javascript and added presplitting functionality, which splits the curve in local extremes (first derivative roots) and after that the AntiGrain method handles also all possible collinear cases:

    Collinear horizontal: http://jsbin.com/ivomiq/6
    Set of different cases: http://jsbin.com/ivomiq/7
    Random: http://jsbin.com/ivomiq/8
    Collinear rotated: http://jsbin.com/ivomiq/9

    All the above samples have two paths in top of each other to show possible errors in adaptive algorithm: the red curve is splitted using very slow brute force method and the green one is splitted using AntiGrain method. If you see not red at all, the AntiGrain's method approximate()-function is working as expected.

    OK, now we have repaired Raphael and repaired AntiGrain. If we combine these both methods, we can create a function that converts ANY svg path element to polygon (single or multiple subpolygons). I'm not 100% sure that this is the best or fastest method, but it should be usable. Of course the best would be native browser implementation...

    0 讨论(0)
提交回复
热议问题