简体   繁体   English

在JavaScript中将SVG路径转换为多边形

[英]Converting svg path to polygon in javascript

i am trying to convert an svg path to an svg polygon in javascript. 我正在尝试将svg路径转换为javascript中的svg多边形。 i found this function to crawl along the path and extract its coordinates. 我发现此功能沿路径爬行并提取其坐标。

    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;

    }

this works but it returns some hundreds of points for a polygon that has only six points originally. 此方法有效,但对于最初仅具有六个点的多边形,它将返回数百个点。 how would i get only the necessary points (all paths are straight lines, no curves) 我将如何仅获得必要的点(所有路径均为直线,无曲线)

ok got it.. the function getPathSegAtLength() returns the number of the actual path segment. 好的..函数getPathSegAtLength()返回实际路径段的编号。 with that it's easy then. 这样就很容易。

    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);

        }

    }

path.getPointAtLength() is good for rough purposes where you don't need both speed and quality. path.getPointAtLength()适用于不需要速度和质量的粗略用途。 If you get every pixel, you get thousands of points, but still the quality is low, because SVG path can have decimal values, eg. 如果获得每个像素,您将获得数千个点,但是质量仍然很低,因为SVG路径可以具有十进制值,例如。 0.1, 0.2. 0.1、0.2。

If you want more precision by calling eg. 如果您想通过调用例如更高的精度。 path.getPointAtLength(0.1) you get easily tens of thousands of points in complex paths and the process last seconds or tens of seconds. path.getPointAtLength(0.1)可以很容易地在复杂路径中获得数万个点,并且该过程持续数秒或数秒。 And after that you have to reduce the count of point ( https://stackoverflow.com/a/15976155/1691517 ), which last again seconds. 然后,您必须减少持续数秒的点数( https://stackoverflow.com/a/15976155/1691517 )。 But still the quality can be low, if wrong points are removed. 但是,如果删除错误的点,质量仍然可能很差。

Better techique is to first convert all path segments to cubic curves eg. 更好的技术是首先将所有路径段转换为三次曲线。 using Raphael's path2curve() and then use some adaptive method ( http://antigrain.com/research/adaptive_bezier/ ) to convert cubic segments to points and you get at the same time both the speed and quality. 使用Raphael的 path2curve(),然后使用一些自适应方法( http://antigrain.com/research/adaptive_bezier/ )将立方线段转换为点,您将同时获得速度和质量。 And after that there is no need to reduce points because the adaptive process itself has parameters to adjust the quality. 之后,由于自适应过程本身具有调整质量的参数,因此无需减少点数。

I have made a function that does all that and I'm going to publish it when it is enough optimized for speed. 我已经做了一个可以完成所有这些工作的函数,并且在速度方面进行了充分优化之后,我将发布它。 The quality and reliability seems to be 100% after testing with thousands of random paths and the speed is yet significantly faster than with path.getPointAtLength() . 经过数以千计的随机路径测试后,质量和可靠性似乎达到了100%,并且速度仍然比path.getPointAtLength()快得多。

To iterate over the segments, use something like this: 要遍历段,请使用类似以下内容的代码:

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

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

If you want to reduce the number of vertices, then you can use Simplify.js as described here . 如果要减少顶点数量,则可以按此处所述使用Simplify.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM