(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(状态变量条目…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
