14

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

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

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

带有分步教程的维基页面: https ://sourceforge.net/p/jsclipper/wiki/Home%206/

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

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


EDIT4:一种可能性是使用 http://p2js.gelicon.biz/en/将 pascal 转换为 javascript 。还没有成功。p2js.exe clipper.pas给出致命错误“找不到裁剪器使用的单位系统”。


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

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


EDIT2:我做了一个例子,它显示了问题。使用左右箭头应用偏移。在一定距离内它工作正常,但随后出现问题。黄色描边多边形就是所谓的原始偏移多边形,AFAIK Clipper lib 提供了一种方法来删除原始偏移多边形中不需要的部分。


Angus Johnson 有一个 Clipper 库,用于偏移多边形。

我需要 Javascript 中的这个功能来抵消 SVG 多边形。

有人制作了它的 Javascript 端口吗?

如果没有,我会很感激一些指导方针,例如。以下内容:
- 这将是多么艰巨的任务?
- 选择哪一个作为源代码(Delphi、C#、C++)?
- lib 中的所有内容都需要抵消吗?

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

偏移多边形、多边形、delta、jointype、miterlimit、jtSquare jtRound jtMiter

一些链接:
- Sourceforge 中的文件
- Clipper 文档
- Stackoverflow 的一个答案
-偏移算法

4

3 回答 3

4

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

需要注意的是,128 位支持减少到 106 位。

优点之一是浏览器空间大,可以使用 svg、vml、html5 画布作为图形界面。

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


编辑:

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

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

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

带有分步教程的维基页面: https ://sourceforge.net/p/jsclipper/wiki/Home%206/

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

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

于 2012-11-27T19:39:25.553 回答
2

多边形膨胀没有简单的解决方案。如果你有一个凹多边形,如果你足够减少偏移量,它迟早会分成几个更小的多边形。所以我建议使用现有的、经过验证的算法(Clipper 应该是一个很好的算法)。

关于将 C# 移植到 JS 的问题,我会说这当然是可能的,但问题是需要多少时间以及自动移植工具是否有用。从这个讨论来看,我对此表示怀疑:

我快速尝试使用 ScriptSharp 将 C# 代码转换为 Javascript,但是有太多不兼容的结构无法使用,我无法让它输出 javascript 文件。下一步似乎是尝试在 Javascript 中实现 Vatti 裁剪算法。

...

是的,它不会帮助您使用各种自动转换工具。裁剪器具有像 Int64 或 Int128 这样的数据结构,它们在 JS 或 AS 中不存在。我只是完全删除了它们。对于大多数情况,Int32 应该足够了,除非你从事与地理或巨幅地图有关的工作。

不幸的是,其中提到的用户之一的 ActionScript 端口不再可用。

于 2012-11-07T07:47:44.260 回答
2
    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;
    }
于 2019-01-17T17:11:02.903 回答