(6)JS-Clipper2之ClipperOffset
1. 描述
ClipperOffset类封装了对打开路径和关闭路径进行偏移(膨胀/收缩)的过程。
这个类取代了现在已弃用的OffsetPaths函数,该函数不太灵活。可以使用不同的偏移量(增量)多次调用Execute方法,而不必重新分配路径。现在可以在一次操作中对开放和封闭路径的混合进行偏移。此外,OffsetPaths的Limit参数的双重功能不仅让一些用户感到困惑,而且当EndType是etRound和Jo时,它也阻止了自定义RoundPrecision被分配。
当偏移闭合路径(多边形)时,重要的是:
- 它们的方向是一致的,即外多边形具有相同的方向,而孔具有相反的方向,
- 它们不自相交。
2.属性
2.1 ClipperLib.ClipperOffset.ArcTolerance
ArcTolerance只有在JoinType是jtRound或者当EndType是开放式轮廓(JoinType = jtRound and/or EndType = etRound)的时候才有效;
ArcTolerance属性(圆弧精度)指定了近似处理弧线时可接受的最大不精确性(“公差”)。
ArcTolerance 默认值为0.25,说明qd(倒角偏离真实圆弧的最大距离)不超过0.25。我们可以发现,qd越小,整个近似圆弧越光滑,代价就是我们需要插入更多的顶点。

将公差降低到0.25以下不会改善平滑度,因为顶点坐标仍将四舍五入为整数值。实现子整数精度的唯一方法是在偏移之前和之后进行坐标缩放(参见下面的示例)。
将ArcTolerance设置为偏移量delta(弧半径)的合理分数是很重要的。相对于偏移delta的较大公差将产生较差的弧近似值,但同样重要的是,非常小的公差将大大降低偏移性能,同时提供不必要的精度。当偏移坐标已被缩放以保持浮点精度的多边形时,这很可能是一个问题。
例如:设想一组多边形(在浮点坐标中定义)将使用圆连接偏移10个单位,解决方案是将浮点精度保持到至少小数点后6位。
为了保持这种程度的浮点精度,并且考虑到Clipper和ClipperOffset都对整数坐标进行操作,在偏移之前,多边形坐标将被缩放108(并四舍五入为整数)。偏移delta和ArcTolerance也需要按相同的因子进行缩放。如果ArcTolerance保持默认的0.25个单位不变,那么解决方案中的每个弧线将包含44000个顶点的一小部分,而最终的弧线不精度将是0.25 × 10-8个单位(即缩放逆转后)。然而,如果在最终未缩放的解决方案中0.1个单位是可接受的不精度,那么ArcTolerance应该设置为0.1 × scaling_factor (0.1 × 108)。现在,如果缩放同样应用于ArcTolerance和Delta Offset,那么在这个例子中,定义每个弧的顶点数(步骤)将是23的一小部分。
Number ArcTolerancevar co = new ClipperLib.ClipperOffset();
co.ArcTolerance = 1.23;
2.2 ClipperLib.ClipperOffset.MiterLimit
该属性包含了一个比例系数(=最大容忍距离/偏置距离),当大于最大容忍距离时,则会使用1*delta距离来进行;
默认的MiterLimit值大小是2,这也是允许的最小MiterLimit大小,如果没有规定合理的MiterLimit,在部分尖锐的拐角处就会形成长的突起,如下图:

3. 方法
3.1 ClipperLib.ClipperOffset()
构造函数
ClipperOffset ClipperOffset(Number miterLimit = 2.0, Number roundPrecision = 0.25);var co = new ClipperLib.ClipperOffset(2.0, 0.25);
构造函数包含了两个可选参数,MiterLimit和ArcTolerance,这两个参数和其同名的属性的含义是相同的。
MiterLimit只是在JoinType是jtMiter的时候才启用,
ArcTolerance只有在JoinType是jtRound或者当EndType是开放式轮廓的时候才有效;
3.2 ClipperLib.ClipperOffset.AddPath()
void AddPath(Path path, JoinType jointype, EndType endtype);var path = [{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}];
var co = new ClipperLib.ClipperOffset(2, 0.25);
co.AddPath(path, ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);
向ClipperOffset对象添加一个路径用来准备偏置;
其中开放式路径只能被偏移一个正值;
这个方法可以被多次调用。
3.3 ClipperLib.ClipperOffset.AddPaths()
向ClipperOffset对象添加路径,为偏移做准备。这个方法可以被多次调用。
void AddPaths(Paths paths, JoinType jointype, EndType endtype);var paths = [[{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 co = new ClipperLib.ClipperOffset(2, 0.25);
co.AddPaths(paths, ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);
3.4 ClipperLib.ClipperOffset.Clear()
清空所有多边形对象
去除了Clipper对象中所有存在的被裁剪对象和裁剪对象,使得该Clipper对象可以重用
void Clear();var path = [{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}];
var co = new ClipperLib.ClipperOffset();
co.AddPath(path, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
co.Clear();
3.5 ClipperLib.ClipperOffset.Execute()
void Execute(Paths solution, Number delta);
void Execute(PolyTree polytree, Number delta);var subj = new ClipperLib.Paths();
var solution = new ClipperLib.Paths();
subj[0] = [{"X":348,"Y":257},{"X":364,"Y":148},{"X":362,"Y":148},{"X":326,"Y":241},{"X":295,"Y":219},{"X":258,"Y":88},{"X":440,"Y":129},{"X":370,"Y":196},{"X":372,"Y":275}];
var scale = 100;
ClipperLib.JS.ScaleUpPaths(subj, scale);
var co = new ClipperLib.ClipperOffset(2, 0.25);
co.AddPaths(subj, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
co.Execute(solution, -7.0);
ClipperLib.JS.ScaleDownPaths(subj, scale);
//draw solution with your own drawing function...
DrawPolygons(solution, 0x4000FF00, 0xFF009900);
该方法有两个参数,
第一个是接受结果的结构(可以是PolyTree或Paths中的一种),
第二个参数是指偏移量的大小–负值会收缩多边形,正值会膨胀扩边多边形。
该方法可以被调用多次,来实现对相同路径实现不同程度的偏置
关于缩放的注意事项:
因为ClipperOffset使用整数坐标,所以你必须缩放坐标以保持精度并使弧线平滑——在整数输入的情况下也是如此。
Javascript Clipper为此提供了四个函数:ScaleUpPath、scaleupppaths、ScaleDownPath和ScaleDownPaths。
如果JoinType为jtRound或EndType为etRound,强烈建议进行缩放
相关文章:
(6)JS-Clipper2之ClipperOffset
1. 描述 ClipperOffset类封装了对打开路径和关闭路径进行偏移(膨胀/收缩)的过程。 这个类取代了现在已弃用的OffsetPaths函数,该函数不太灵活。可以使用不同的偏移量(增量)多次调用Execute方法,而不必重新分配路径。现在可以在一次操作中对开放和封闭路…...
如何在Ubuntu中利用repo和git地址下载获取imx6ull的BSP
01-设置git的用户名和邮箱 git config --global user.name "suwenhao" git config --global user.email "2487872782qq.com"这里不设置的话后面在第5步的repo配置中还是会要求输入,而且以后进行相关操作都要输入,不妨现在就进行配置…...
Ruby On Rails 笔记5——常用验证下
3.Validation Options 3.1 :allow_nil 当验证值为nil时:allow_nil选项会跳过验证 class Coffee < ApplicationRecordvalidates :size, inclusion: { in: %w(small medium large),message: "%{value} is not a valid size" }, allow_nil: true end irb> Cof…...
JS听到了因果的回响
这是我学习JS的第11天了,,,我现在赶着周末学JS,然后还有二十多天就期末了呵呵呵。。。 图片切换模块 思路分析: 这是实现的代码,建议还是把不同的变量定义出来比较合适: //获取三个盒子// 小盒…...
【高中生讲机器学习】28. 集成学习之 Bagging 随机森林!
创建时间:2024-12-09 首发时间:2024-12-09 最后编辑时间:2024-12-09 作者:Geeker_LStar 嘿嘿,你好呀!我又来啦~~ 前面我们讲完了集成学习之 Boooooosting,这篇我们来看看集成学习的另一个分支…...
硬件设计 | Altium Designer软件PCB规则设置
基于Altium Designer(24.9.1)版本 嘉立创PCB工艺加工能力范围说明-嘉立创PCB打样专业工厂-线路板打样 规则参考-嘉立创 注意事项 1.每次设置完规则参数都要点击应用保存 2.每次创建PCB,都要设置好参数 3.可以设置默认规则,将…...
【Elasticsearch】实现用户行为分析
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
python字符串处理基础操作总结
1.去掉空格或者特殊符号 input_str.strip() #去掉所有空格 input_str.lstrip() #去掉左边空格 input_str.rstrip() #去掉右边空格 def print_hi():input_str 今天天气不错,风和日丽 out input_str.strip()print(input_str)print(out)if __name__ __main__:print…...
电子商务人工智能指南 6/6 - 人工智能生成的产品图像
介绍 81% 的零售业高管表示, AI 至少在其组织中发挥了中等至完全的作用。然而,78% 的受访零售业高管表示,很难跟上不断发展的 AI 格局。 近年来,电子商务团队加快了适应新客户偏好和创造卓越数字购物体验的需求。采用 AI 不再是一…...
【论文阅读】相似误差订正方法在风电短期风速预报中的应用研究
文章目录 概述:摘要1. 引言2. 相似误差订正算法(核心)3. 订正实验3.1 相似因子选取3.2 相似样本数试验3.3 时间窗时长实验 4. 订正结果分析4.1 评估指标对比4.2 风速曲线对比4.3 分风速段订正效果评估4.4 风速频率统计 5. 结论与讨论 概述&am…...
贪心算法 - 学习笔记 【C++】
2024-12-09 - 第 38 篇 贪心算法 - 学习笔记 作者(Author): 郑龙浩 / 仟濹(CSND账号名) 贪心算法 学习课程: https://www.bilibili.com/video/BV1f84y1i7mv/?spm_id_from333.337.search-card.all.click&vd_source2683707f584c21c57616cc6ce8454e2b 一、基本…...
精确的单向延迟测量:使用普通硬件和软件
论文标题:Precise One-way Delay Measurement with Common Hardware and Software(精确的单向延迟测量:使用普通硬件和软件) 作者信息:Maciej Muehleisen 和 Mazen Abdel Latif,来自Ericsson Research Eri…...
【MySQL 进阶之路】存储引擎和SQL优化技巧分析
1.InnoDB和MyISAM存储引擎的区别是什么?你在哪些场景下选择InnoDB? Innodb是高并发,支持事务跟行级锁,myisam不支持事务和行级锁,支持表级锁,不支持高并发。innodb底层是B树,适合范围查询&#…...
vue+elementUI从B页面回到A页面并且定位到A页面的el-tabs的某个页签
场景 做项目碰到一个需求,不能使用组件缓存keep-alive,但是需要跳转到B页面后,点击B页面的返回回到A页面的某个页签,灵机一动利用路由拦截去判断即将要跳转的页面后,在获取vm里对应的标签变量进行赋值,实现…...
{结对编程/大模型} 实践营项目案例 | 基于RAG搭建政策问答智能聊天助手
在构建政策问答智能聊天助手的过程中,我们采用了 RAG(Retrieval-Augmented Generation)技术。RAG 是一种结合了检索和生成的混合型自然语言处理技术,它通过检索相关信息来增强生成模型的上下文理解能力。RAG 的主要优点在于能够有…...
【Canvas与图标】乡土风金属铝边立方红黄底黑字图像处理图标
【成图】 120*120图标: 大小图: 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>金属铝边立方红黄底黑…...
【开源】A064—基于JAVA的民族婚纱预定系统的设计与实现
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看项目链接获取⬇️,记得注明来意哦~🌹 赠送计算机毕业设计600个选题ex…...
C++实现一个经典计算器(逆波兰算法)附源码
1、本篇要实现的内容 最近,大家讨论计算器的实现比较热,今天我也来用C和Visual Studio实现一个计算器的小程序。这里使用逆波兰算法,能够根据当前用户输入的算式表达式字符串,计算出所要的结果,算式字符串可以包括加、…...
Python知识分享第二十二天-数据结构入门
数据结构 “”" 基础概念: 程序 数据结构 算法 数据结构 存储和组织数据的方式. 算法 解决问题的思维, 思路, 方式. 算法的特性:独立性: 算法 思维, 是解决问题的思路和方式, 不依赖语言.5大特性: 有输入, 有输出, 有穷性, 确定性, 可行性.问: 如何衡量算法的优劣?…...
【WRF理论第十三期】详细介绍 Registry 的作用、结构和内容
目录 1. Introduction:介绍 Registry 的作用和功能。2. Registry Contents:详细描述 Registry 的结构和内容,包括各个部分的条目类型。2.1. DIMSPEC ENTRIES(维度规格条目)2.2. STATE ENTRIES(状态变量条目…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
