问题描述
我正在尝试使用。
以多边形开始然后执行操作,然后它似乎将它们转换回SVG路径。
JS Clipper starts with polygons then performs the operation and then it seems to convert them back to SVG paths.
下面的函数给出了一个SVG路径,但下面的例子以2个多边形开始。
The function below gives an SVG path but the below example starts with 2 polygons.
一个示例函数:
// Polygon Arrays are expanded for better readability
function clip() {
var subj_polygons = [
[{
X: 10,
Y: 10
}, {
X: 110,
Y: 10
}, {
X: 110,
Y: 110
}, {
X: 10,
Y: 110
}],
[{
X: 20,
Y: 20
}, {
X: 20,
Y: 100
}, {
X: 100,
Y: 100
}, {
X: 100,
Y: 20
}]
];
var clip_polygons = [
[{
X: 50,
Y: 50
}, {
X: 150,
Y: 50
}, {
X: 150,
Y: 150
}, {
X: 50,
Y: 150
}],
[{
X: 60,
Y: 60
}, {
X: 60,
Y: 140
}, {
X: 140,
Y: 140
}, {
X: 140,
Y: 60
}]
];
var scale = 100;
subj_polygons = scaleup(subj_polygons, scale);
clip_polygons = scaleup(clip_polygons, scale);
var cpr = new ClipperLib.Clipper();
cpr.AddPolygons(subj_polygons, ClipperLib.PolyType.ptSubject);
cpr.AddPolygons(clip_polygons, ClipperLib.PolyType.ptClip);
var subject_fillType = ClipperLib.PolyFillType.pftNonZero;
var clip_fillType = ClipperLib.PolyFillType.pftNonZero;
var clipTypes = [ClipperLib.ClipType.ctUnion];
var clipTypesTexts = "Union";
var solution_polygons, svg, cont = document.getElementById('svgcontainer');
var i;
for (i = 0; i < clipTypes.length; i++) {
solution_polygons = new ClipperLib.Polygons();
cpr.Execute(clipTypes[i], solution_polygons, subject_fillType, clip_fillType);
console.log(polys2path(solution_polygons, scale));
}
}
// helper function to scale up polygon coordinates
function scaleup(poly, scale) {
var i, j;
if (!scale) scale = 1;
for (i = 0; i < poly.length; i++) {
for (j = 0; j < poly[i].length; j++) {
poly[i][j].X *= scale;
poly[i][j].Y *= scale;
}
}
return poly;
}
// converts polygons to SVG path string
function polys2path(poly, scale) {
var path = "",
i, j;
if (!scale) scale = 1;
for (i = 0; i < poly.length; i++) {
for (j = 0; j < poly[i].length; j++) {
if (!j) path += "M";
else path += "L";
path += (poly[i][j].X / scale) + ", " + (poly[i][j].Y / scale);
}
path += "Z";
}
return path;
}
推荐答案
我假设你的意思是某种svg路径到多边形转换。
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路径可以包含十个不同的段,如果我们考虑相对和绝对坐标,则为20。它们在路径元素的d属性中表示为字母:相对的是 mhvlcqastz
,绝对的是 MHVLCQASTZ
。每个都有不同的属性, a
(椭圆弧)是最复杂的属性。最可用和最灵活的类型是 c
(三次贝塞尔曲线),因为它可以以相当高的精度表示所有其他类型,如下例所示:,。
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库有 Path2Curve
-function可以将所有路径段转换为三次曲线,它还可以处理复杂的弧到立方转换。不幸的是它有一个bug,所以它无法处理所有可能的路径段组合,但幸运的是有一个固定版本的库可用:(查看Javascript窗口)。
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).
当所有路径段都被转换时对于三次曲线,它们可以转换为单独的线段。有几种方法,最佳似乎是,它产生更多的线段在曲线的急转弯中,曲线的其他部分更少,以实现曲线保真度和低计数段的平衡,以最大化渲染速度,但不幸的是它无法处理所有共线情况。我成功地将AntiGrain的方法转换为Javascript并添加了预分割功能,它将曲线分成局部极值(一阶导数根),之后AntiGrain方法也处理所有可能的共线情况:
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:
共线水平:
一组不同的案例:
随机:
共线旋转:
以上所有样本都有两条相互叠加的路径,以显示自适应算法中可能存在的错误:使用非常慢的强力方法分割红色曲线,使用AntiGrain方法分割绿色曲线。如果你看不到红色,AntiGrain的方法 approximate() - function
正在按预期工作。
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 ,现在我们修复了Raphael并修复了AntiGrain。如果我们将这两种方法结合起来,我们就可以创建一个将ANY svg路径元素转换为多边形(单个或多个子多边形)的函数。我不是100%确定这是最好或最快的方法,但它应该是可用的。当然最好的是本机浏览器实现......
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...
这篇关于将SVG路径转换为多边形以在Javascript Clipper中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!