在Javascript中抵消多边形

时间:2012-11-06 10:19:00

标签: javascript svg geometry script#

EDIT5:最后用Javascript实现了Angus Johnson的Clipper库,并为主机选择了Sourceforge。

现场演示:http://jsclipper.sourceforge.net/6.1.1.1/main_demo.html

下载源代码: https://sourceforge.net/projects/jsclipper/

Wikipage一步一步的教程: https://sourceforge.net/p/jsclipper/wiki/Home%206/

演示包括数十个样本多边形的演示程序: https://sourceforge.net/p/jsclipper/wiki/Main_Demo%206/

我希望这可以帮助任何需要折线和多边形剪裁库的人使用偏移功能。


EDIT4:一种可能性是将pascal转换为javascript使用 http://p2js.gelicon.biz/en/。尚未成功。 p2js.exe clipper.pas给出致命错误"无法找到限幅器使用的单位系统"。


编辑:我找到了script#Github),它似乎能够将C#转换为Javascript。 Clipper lib在C#中可用,那么可以使用Script#进行C# - > JS转换吗?

EDIT3:没有使用脚本#转换,但也有Emscripten,但是4000 cpp行转换为300 000个Javascript行,所以不是一个选项。手动转换似乎是一个王者。


EDIT2:我发了an example,显示了问题。使用向左和向右箭头应用偏移量。在一定距离内它可以正常工作,但随后会出现问题。黄色描边多边形是所谓的原始偏移多边形,AFAIK Clipper lib提供了一种方法来处理删除原始偏移多边形的不需要的部分。


Angus Johnson有一个Clipper库用于抵消多边形。

我在Javascript中需要此功能来抵消SVG多边形。

有人制作了Javascript端口吗?

如果没有,我会欣赏一些指导原则,例如。以下内容:
- 这将是多么艰巨的任务? - 选择哪一个来源(Delphi,C#,C ++)?
- 抵消需要lib中的所有内容吗?

Clipper库产生以下结果,这些结果只是所需的功能:

Offset Polygons, polygons, delta, jointype, miterlimit, jtSquare jtRound jtMiter

一些链接:
- Files in Sourceforge
- Clipper Documentation
- One Stackoverflow answer
- Offsetting algorithm

2 个答案:

答案 0 :(得分:4)

我已成功将剪辑器移植到JS,过了一段时间,经过彻底的测试后才发布它。似乎所有功能都可以移植。

一个警告,128位支持减少到106位。

其中一个优点是可以使用svg,vml,html5 canvas作为图形界面。

任何想法,哪个主持人最容易发布,有演示可能性?


编辑:

最后用Javascript实现了Angus Johnson的Clipper库,并为主机选择了Sourceforge。

现场演示: http://jsclipper.sourceforge.net/6.1.1.1/main_demo.html

下载: https://sourceforge.net/projects/jsclipper/

Wikipage一步一步的教程: https://sourceforge.net/p/jsclipper/wiki/Home%206/

演示包括数十个样本多边形的演示程序: https://sourceforge.net/p/jsclipper/wiki/Main_Demo%206/

我希望这可以帮助任何需要折线和多边形剪裁库的人使用偏移功能。

答案 1 :(得分:0)

    function offsetPoints(pts, offset) {
        let newPoints = [];
        for (let j = 0; j < pts.length; j++) {
            let i = (j - 1);
            if (i < 0) i += pts.length;
            let k = (j + 1) % pts.length;

            let v1 = [pts[j].x - pts[i].x, pts[j].y - pts[i].y];
            let mag1 = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1])
            v1 = [v1[0] / mag1, v1[1] / mag1]
            v1 = [v1[0] * offset, v1[1] * offset]
            let n1 = [-v1[1], v1[0]];
            let x1 = pts[i].x + n1[0];
            let y1 = pts[i].y + n1[1];
            let x2 = pts[j].x + n1[0];
            let y2 = pts[j].y + n1[1];

            let v2 = [pts[k].x - pts[j].x, pts[k].y - pts[j].y];
            let mag2 = Math.sqrt(v2[0] * v2[0] + v2[1] * v2[1])
            v2 = [v2[0] / mag2, v2[1] / mag2]
            v2 = [v2[0] * offset, v2[1] * offset]
            let n2 = [-v2[1], v2[0]];
            let x3 = pts[j].x + n2[0];
            let y3 = pts[j].y + n2[1];
            let x4 = pts[k].x + n2[0];
            let y4 = pts[k].y + n2[1];

            let den = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
            let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / den;
            let x = x1 + ua * (x2 - x1);
            let y = y1 + ua * (y2 - y1);

            newPoints.push({ x, y });
        }

        return newPoints;
    }