2013-04-12 85 views
1

我想将一个svg路径转换为javascript中的svg多边形。我发现这个函数沿路径爬行并提取其坐标。在JavaScript中将svg路径转换为多边形

var length = path.getTotalLength(); 
    var p=path.getPointAtLength(0); 
    var stp=p.x+","+p.y; 

    for(var i=1; i<length; i++){ 

     p=path.getPointAtLength(i); 
     stp=stp+" "+p.x+","+p.y; 

    } 

这个工作原理,但它返回几百点,原来只有六点的多边形。我怎么会只得到必要的点(所有的路径是直线,没有曲线)

+0

我敢打赌,您需要确定自上次迭代以来x或y值之一发生了变化,这意味着方向发生了变化。只有这样你才能抓住这一点。 – Ian

+0

可以减少点数,但它仍然在1000点左右..我需要6. – aushilfe444

+0

你能够提供一个带有SVG和代码的jsFiddle吗? – Ian

回答

4

确定了它..函数getPathSegAtLength()返回实际路径段的数量。那很容易。

var len = path.getTotalLength(); 
    var p=path.getPointAtLength(0); 
    var seg = path.getPathSegAtLength(0); 
    var stp=p.x+","+p.y; 

    for(var i=1; i<len; i++){ 

     p=path.getPointAtLength(i); 

     if (path.getPathSegAtLength(i)>seg) { 

     stp=stp+" "+p.x+","+p.y; 
     seg = path.getPathSegAtLength(i); 

     } 

    } 
0

遍历段,使用这样的:

var segList = path.normalizedPathSegList; // or .pathSegList 

for(var i=1; i<segList.numberOfSegments; i++){ 
    var seg = segList.getItem(i); 
} 

如果你想减少顶点的数量,那么你可以使用Simplify.js作为described here

1

path.getPointAtLength()适合粗糙的目的,你不需要速度和质量。如果你得到每一个像素,你会得到数千个点,但质量仍然很低,因为SVG路径可以有十进制值,例如。 0.1,0.2。

如果你想通过调用更高的精度例如。 path.getPointAtLength(0.1)您可以在复杂路径中轻松获得数万个点,并且该过程持续数秒或数十秒。之后,你必须减少点的数量(https://stackoverflow.com/a/15976155/1691517),这又持续了几秒钟。但如果删除了错误的分数,质量仍然很低。

更好的技术是首先将所有路径段转换为三次曲线,例如。使用Raphael's path2curve(),然后使用一些自适应方法(http://antigrain.com/research/adaptive_bezier/)将立方片段转换为点,并同时获得速度和质量。之后,不需要减少点数,因为自适应过程本身具有调整质量的参数。

我已经做了所有这些功能,并且我将在足够优化速度时发布它。经过数千条随机路径的测试后,质量和可靠性似乎达到100%,速度仍然快于path.getPointAtLength()

+0

谢谢你的努力,但在我的情况下,我只用直线工作,正如我所说,所以这不会是必要的 – aushilfe444

+0

@Timo - 你有没有发布你的算法? – jhamm

+0

@jhamm这可能会对您有帮助。 http://stackoverflow.com/a/15890424/1691517 –