首页 > 其他分享 >(2)JS-Clipper2之Clipper

(2)JS-Clipper2之Clipper

时间:2024-12-09 17:28:43浏览次数:6  
标签:Clipper 10 多边形 ClipperLib JS 110 var Clipper2

1.类描述       

        Clipper类封装了多边形上的布尔运算(交集、并并、差和异或),也称为多边形裁剪。输入多边形(主题subject 和剪辑集 clip sets)通过Clipper对象的AddPath和AddPaths方法传递给它,剪辑操作通过调用它的Execute方法执行。通过重复调用Execute,可以对相同的输入多边形集执行多个布尔运算。

2.类属性

2.1 ClipperLib.Clipper.PreserveCollinear

Boolean PreserveCollinear;

          默认情况下,当三个或更多顶点在输入的多边形(主题subject 或剪辑clip)中共线时,Clipper对象会在剪切之前删除“内部”顶点。启用时,PreserveCollinear属性会阻止这种默认行为,以允许这些内部顶点出现在解决方案中。

var cpr = new ClipperLib.Clipper();
cpr.PreserveCollinear = true;

2.2 ClipperLib.Clipper.ReverseSolution

Boolean ReverseSolution;

当此属性设置为true时,Execute()方法的solution参数中返回的多边形将具有与其正常方向相反的方向。反转

var cpr = new ClipperLib.Clipper();
cpr.ReverseSolution = true;

2.3 ClipperLib.Clipper.StrictlySimple

术语:

(1)简单多边形是指不自相交的多边形。

(2)弱简单多边形是包含“接触”顶点或“接触”边的简单多边形。

多边形两个点,共用一个坐标,但不相邻,则他们"接触".

如果一条边的一个端点与另一条边接触,但不包括其相邻边,或者它们共线且重叠(包括相邻边),则该边与另一条边接触。

(3)严格简单多边形是不包含“接触”顶点或“接触”边的简单多边形。

在多边形剪裁操作(通过执行Clipper.Execute()返回的新的多边形),默认返回的简单多边形。

如果使用Boolean StrictlySimple属性是,若为true则返回严格简单多边形,若为false返回若简单多边形。不启用该属性,默认返回简单多边形。

严格简单多边形的计算成本比较高,因此默认情况下不启用

上图显示了,两个弱简单多边形,被分解成两个严格简单的多边形。(带箭头的轮廓旨在帮助可视化顶点顺序。

var cpr = new ClipperLib.Clipper();
cpr.StrictlySimple = true;

2.4 ClipperLib.Clipper.ZFillFunction

启用预处理器指令ClipperLib.use_xyz时,向IntPoit结构中添加Z成员变量,便于用户可以存储自定义的数据。(默认IntPoit结构 X,Y坐标点,且都是整数)

ClipperLib.use_xyz = true;

具体用法待学习???????????

3.类方法

3.1 ClipperLib.Clipper()

Clipper Clipper(InitOptions initOptions = 0);
其中InitOptions如下
Number ioReverseSolution = 1;
Number ioStrictlySimple = 2;
Number ioPreserveCollinear = 4;

 Clipper构造函数,创建Clipper类的一个实例。InitOptions作为参数传递来设置相应的属性。构造函数中设置该参数之后,后面还可以在修改

用法

var cpr = new ClipperLib.Clipper();
// or
var cpr = new ClipperLib.Clipper(ClipperLib.Clipper.ioStrictlySimple | ClipperLib.Clipper.ioPreserveCollinear);
// or
var cpr = new ClipperLib.Clipper(2 | 4);

3.2 ClipperLib.Clipper.Area()

var area = ClipperLib.Clipper.Area(polygon);

计算路径是闭合closed path 的多边形面积。返回结果有正负之分

正负值的意义
正值:表示多边形的顶点顺序是逆时针方向。
负值:表示多边形的顶点顺序是顺时针方向。

3.3 ClipperLib.Clipper.CleanPolygon()

//Number distance 指定距离范围内,实际上就是一个容差
Path CleanPolygon(Path path, Number distance)

多边形若存在顶点接触,或者轻微自相交.该函数将防止多边形因此引起的变形问题。

通过删除相关点集实现,那么具体要移除那些类型的点集:

  • (1)连接点共线的边,或者近似共线的边(近似,就是指定距离范围内)
  • (2)距离过劲的相邻点(此处距离就是设置的 距离范围内)
  • (3)在次相邻(即:两个点之间还有一个点,且是无关点)的线段以及无关线段之间距离过小(在指定范围内)

当顶点被单个(外置)顶点分开时,它们是半相邻的。

Number distance距离参数的默认值约为\sqrt{2},因此当相邻或半相邻顶点的对应X和Y坐标相差不超过1个单位时,将删除顶点。(如果这些边是半相邻的,那么外围的顶点也会被移除。)

经测试,偏移前去除伪影最合适的距离值是0.1 *scale

上述两个多边形,第一个最后一个点,会被删除点(最终是一个四个点的正方形)。第二多边形,第4和5两个点将被删除掉(最终是一个三角形)

另外一个代码例子:

var path = [{"X":10,"Y":10},{"X":11,"Y":11},{"X":110,"Y":10},{"X":110,"Y":110},
{"X":10,"Y":110}]; 
var cleaned_path = ClipperLib.Clipper.CleanPolygon(path, 1.1);
// point {"X":11,"Y":11} 点会被移除掉

3.4 ClipperLib.Clipper.CleanPolygons()

 与CleanPolygon中的功能相同,但参数类型为Paths。经测试,偏移前去除伪影最合适的距离值为0.1 *scale

3.5 ClipperLib.Clipper.ClosedPathsFromPolyTree()

 这个函数从PolyTree结构中过滤出开放路径,只返回paths结构中的封闭路径。

Paths ClosedPathsFromPolyTree(PolyTree polytree)

3.6 ClipperLib.Clipper.Execute()

确定了subject 和 clip paths路径后(通过前面函数AddPath and/or AddPaths),然后Execute可以执行clipType参数指定的裁剪操作(交集、并集、差值或异或)。

Boolean Execute(ClipType clipType,
  Paths solution,
  PolyFillType subjFillType,
  PolyFillType clipFillType);

Boolean Execute(ClipType clipType,
  PolyTree solution,
  PolyFillType subjFillType,
  PolyFillType clipFillType);

3.6.1 clipType参数

有四种布尔运算:AND、OR、NOT和XOR。具体四种布尔运算方式介绍如下

https://sourceforge.net/p/jsclipper/wiki/documentation/#clipperlibcliptype

3.6.2 solution参数

该参数可以是Paths或PolyTree结构类型。Paths结构比PolyTree结构更简单和更快(大约10%)。PolyTree保存路径的父子关系信息,以及它们是打开还是关闭。

3.6.3 subjFillType和clipFillType参数

分别定义了应用于主题subject 和剪辑clip路径中的多边形(即闭合路径)的多边形填充规则。(通常情况下,两组多边形使用相同的填充规则显然不是必要的。)

代码示例

function DrawPolygons(paths, color)
{/* ... */}

function Main(args)
{
  var subj = [[{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 = [[{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}]];   
  DrawPolygons(subj, 0x8033FFFF);
  DrawPolygons(clip, 0x80FFFF33);

  var solution = new ClipperLib.Paths();
  var c = new ClipperLib.Clipper();
  c.AddPaths(subj, ClipperLib.PolyType.ptSubject, true);
  c.AddPaths(clips, ClipperLib.PolyType.ptClip, true);
  c.Execute(ClipperLib.ClipType.ctIntersection, solution);

  DrawPolygons(solution, 0x40808080);
}
Main();

3.7 ClipperLib.Clipper.GetBounds()

 此方法返回路径的与轴对齐的边界矩形。就是X,Y最大和最小坐标组成包围盒,矩形。

IntRect GetBounds(Paths paths);

var paths = [[{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]];
var bounds = ClipperLib.Clipper.GetBounds(paths);
// bounds 结果 {"left":10,"top":10,"right":110,"bottom":110}

3.8 ClipperLib.Clipper.MinkowskiDiff()

Paths MinkowskiDiff(Path poly, Path path, Boolean isClosed)

 闵可夫斯基差分是通过从开放或封闭路径的点集中减去多边形中的每个点来实现的。闵可夫斯基差分的一个关键特征是,当它应用于两个多边形时,当两个多边形接触或重叠时,生成的多边形将包含坐标空间原点。(这个函数通常用于确定多边形碰撞的时间。)

简单理解:两个多边形“相减”,并非交集,差集之类的。相减后形成新的图形,该图形如果包括坐标原点(即0,0)那么说明原来两个多边形有交叉,碰撞到一起了。

具体看博文:动手学运动规划:1.4 碰撞检测算法:GJK_minkowskidifference-CSDN博客

3.9 ClipperLib.Clipper.MinkowskiSum()

闵可夫斯基加法是通过将多边形“图案”中的每个点添加到开放或封闭路径中的点集来执行的。生成的多边形(或多个多边形)定义了“模式”在从“路径”的起点移动到终点时将经过的区域。

Paths MinkowskiSum(Path pattern, Path path, Boolean pathIsClosed)
Paths MinkowskiSum(Path pattern, Paths paths, PolyFillType pathFillType, Boolean pathIsClosed)


// Star shape ...
var path = [{"X":89.85,"Y":355.85},{"X":131.72,"Y":227.13},{"X":22.1,"Y":147.57},{"X":157.6,"Y":147.57},{"X":199.47,"Y":18.85},{"X":241.34,"Y":147.57},{"X":376.84,"Y":147.57},{"X":267.22,"Y":227.13},{"X":309.09,"Y":355.85},{"X":199.47,"Y":276.29}];
// Diagonal brush shape ...
var shape = [{"X":4,"Y":-6},{"X":6,"Y":-6},{"X":-4,"Y":6},{"X":-6,"Y":6}];
var solution = ClipperLib.Clipper.MinkowskiSum(shape, path, true);

3.10 ClipperLib.Clipper.OffsetPaths()

弃用,具体参建ClipperLib.ClipperOffset()章节

3.11 ClipperLib.Clipper.OpenPathsFromPolyTree()

Paths OpenPathsFromPolyTree(PolyTree polytree)

// ... polytree is populated automatically by Execute()
var lines = ClipperLib.Clipper.OpenPathsFromPolyTree(polytree);

这个函数过滤掉PolyTree结构中的封闭路径,只返回paths结构中的开放路径

3.12 ClipperLib.Clipper.Orientation()

var orientation = ClipperLib.Clipper.Orientation(polygon);

如果多边形面积为>=0,则返回true。

主要针对封闭的多边形,确定多边形顶点的顺序,顺时针还是逆时针。

方向也依赖于轴方向:

在y轴正向上显示时,如果多边形的方向是逆时针的,则方向将返回true。

在y轴正向下显示时,如果多边形的方向是顺时针方向,则Orientation将返回true。

注释:

  • 自相交多边形具有不确定的方向,在这种情况下,此函数将不会返回有意义的值。
  • 大多数2D图形显示库(如GDI、GDI+、XLib、Cairo、AGG、Graphics32)甚至SVG文件格式的坐标原点都位于各自视口的左上角,Y轴向下递增。然而,一些显示库(如Quartz, OpenGL)的坐标原点未定义或处于经典的左下角位置,Y轴向上增加。
  • 对于非零填充多边形,孔的方向必须与外多边形的方向相反。
  • 对于Clipper的Execute方法返回的解决方案中的闭合路径(多边形),它们的方向对于外部多边形将始终为true,对于孔多边形将始终为false(除非启用了ReverseSolution属性)。

3.13 ClipperLib.Clipper.PointInPolygon()

Number PointInPolygon(IntPoint pt, Path poly)

var poly = [{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}];
var pt = new ClipperLib.IntPoint(50,50);
var inpoly = ClipperLib.Clipper.PointInPolygon(pt, poly);
// inpoly is 1, which means that pt is in polygon

判断点pt在多边形poly的内部,边上,外部

-1:在多边形边上

0:外部

1:在多边形内部

3.14 ClipperLib.Clipper.PolyTreeToPaths()

Paths PolyTreeToPaths(PolyTree polytree)

// ... polytree is populated automatically by Execute()
var paths = ClipperLib.Clipper.PolyTreeToPaths(polytree);

这个函数将PolyTree结构转换为Paths结构(无论它们是打开的还是关闭的)。要区分打开和关闭的路径,使用OpenPathsFromPolyTree或ClosedPathsFromPolyTree。

3.15 ClipperLib.Clipper.ReversePath()

// Call Path.reverse().

var path = [{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}];
path.reverse();
// path is now [[{"X":10,"Y":110},{"X":110,"Y":110},{"X":110,"Y":10},{"X":10,"Y":10}]]

反转路径中顶点的顺序(以及方向)。

3.16 ClipperLib.Clipper.ReversePaths()

反转每个包含路径中的顶点顺序(以及方向)。同上,只不过路径变为集合,多个path

void ReversePaths(Paths p)

var paths = [[{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]];
ClipperLib.Clipper.ReversePaths(paths);
// paths is now [[{"X":10,"Y":110},{"X":110,"Y":110},{"X":110,"Y":10},{"X":10,"Y":10}]]

3.17 ClipperLib.Clipper.SimplifyPolygon()

Paths SimplifyPolygon(Path poly, PolyFillType fillType = PolyFillType.pftEvenOdd)


// five-pointed star with self-intersections...
var five_pointed_star = [{"X":147,"Y":313},{"X":247,"Y":34},{"X":338,"Y":312},{"X":86,"Y":123},{"X":404,"Y":124}];
var ten_pointed_star = ClipperLib.Clipper.SimplifyPolygon(five_pointed_star, ClipperLib.PolyFillType.pftNonZero);
// ten_pointed_star is a ten-pointed star with no self-intersections
var fifteen_pointed_star = ClipperLib.Clipper.SimplifyPolygon(five_pointed_star, ClipperLib.PolyFillType.pftEvenOdd);
// fifteen_pointed_star is a fifteen-pointed star with no self-intersections

从提供的多边形中移除自交点(通过使用指定的PolyFillType执行布尔联合操作)。
具有非连续重复顶点的多边形(即“接触”)将被分割为两个多边形。

3.18 ClipperLib.Clipper.SimplifyPolygons()

同上,只不过参数 Paths polys变成了多个多边形

标签:Clipper,10,多边形,ClipperLib,JS,110,var,Clipper2
From: https://blog.csdn.net/yilvqingtai/article/details/144326111

相关文章

  • (6)JS-Clipper2之ClipperOffset
    1.描述ClipperOffset类封装了对打开路径和关闭路径进行偏移(膨胀/收缩)的过程。这个类取代了现在已弃用的OffsetPaths函数,该函数不太灵活。可以使用不同的偏移量(增量)多次调用Execute方法,而不必重新分配路径。现在可以在一次操作中对开放和封闭路径的混合进行偏移。此外,Off......
  • Wiki.js LDAP 配置
    简介:wiki.js配置的windowsAD域ldap登录本示例使用不带@域名的精简用户名登录wiki.js 截图:  问题:有的用户提示Missingorinvalidemailaddressfromprofile.配置文件中的电子邮件地址丢失或无效。经查,是活动目录中未设置邮件的用户登录无效,和提示的内容一致,在活动......
  • c#通过串口读取到的分段json提取方法
    privateList<byte>receivedBuffer=newList<byte>();privatevoidbtnConnect_Click(objectsender,EventArgse){this.btnConnect.Enabled=false;this.btnDisconnect.Enabled=true;_deviceAdapter=newComDeviceAdapter(this......
  • node.js毕设基于SpringoBoot的新能源汽车租赁换电管理系统的设计与实现 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景随着新能源汽车产业的蓬勃发展,新能源汽车租赁业务逐渐兴起。关于新能源汽车租赁管理的研究,现有研究主要以传统充电模式下的租赁管理为主,专门针对换电模......
  • node.js毕设基于springboot的医疗管理系统 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景在当今医疗行业不断发展的背景下,国内外对于医疗管理系统的研究众多。现有研究主要以大型综合医院的管理系统为主,侧重于医院内部流程的信息化管理,如一些......
  • jsp中的9大内置对象。
    jsp的内置对象表示该对象无需自己创建,而是jsp帮你创建好的对象,对象名必须固定。out:输出对象out.print("");把内容输出到网页中out.flush():刷新request:请求对象---获取客户请求时的内容getParamater("参数名"):获取参数setCharacterEncoding("utf-8");设置编码getSes......
  • vue.js组件开发的常见问题及解决
    组件通信问题父子组件通信问题描述:父子组件之间如何传递数据和方法是常见问题。例如,父组件的数据如何传递给子组件,子组件如何将内部的数据变化通知给父组件。技术解决方案:属性绑定(Props):父组件通过在子组件标签上使用自定义属性(props)将数据传递给子组件。例如,在父组......
  • 在Vue3中如何使用H.265流媒体播放器EasyPlayer.js网页直播/点播播放器?
    随着技术的发展,越来越多的H5流媒体播放器开始支持H.265编码格式。例如,EasyPlayer.js播放器能够支持H.264、H.265等多种音视频编码格式,这使得播放器能够适应不同的视频内容和网络环境。在Vue3中如何使用EasyPlayer.js播放器?具体流程如下:1)首先通过npm引入easyplayer.js;npminst......
  • 视频流媒体播放器EasyPlayer.js无插件H5播放器,如何测试demo视频?
    EasyPlayer.js播放器作为一款功能全面的H5流媒体播放器,凭借其多种协议支持、多种解码方式、丰富的渲染元素和强大的应用功能,以及出色的跨平台兼容性,为用户提供了高度定制化的选项和优化的播放体验。无论是视频直播还是点播,EasyPlayer.js视频流媒体播放器都能满足各种复杂场景下的......
  • js轻量级计数器动画特效插件
    countUp.js是一款轻量级的、无依赖的js计数器动画特效插件。它能够帮助我们快速的通过多种方式创建计数器的动态变化效果。通过设置startVal和endVal参数,countUp可以在任何一个方向上计数。countUp兼容新超强,兼容所有的浏览器。在线演示 下载 可用参数target :html元素......