【计算几何】Clipper的偏移

本文涉及知识点

数学 几何

拐点类型(JoinType)

白色原图;红色尖角(斜接),延长到交点。黄色,圆角,用圆弧过渡,就是通常说的倒圆角。绿色,方角(Square),下面解释。斜切,用直线线连接两个端点。

斜接

白色矩形各边偏移300后,形成白色四条线段。红线是斜接方式偏移矩形。

圆角

红色是圆角方式偏移矩形。

方角

红色是直角方式偏移矩形。先延长线段,再用直线段连接。

斜切

红色是以斜切方式偏移矩形。

miterLimit

斜接如果造成的尖锐的角,超过miterLimit的限制,则转成直角方式。当尖角长度超过 miterLimit × delta 时,转换规则。

首位端点类型

平头方头圆头

白线原图,青色线段平头,绿色折线方头,黄色半圆圆头。

多边形

连接

结果是带空洞的多边形。

代码

csharp 复制代码
        [CommandMethod("QSMInflatePaths")]
        public void InflatePaths()
        {
            CPLineSelInfo selInfo = new CPLineSelInfo();
            CSelEntity sel = new CSelEntity() { m_messageForAdd = "可以选择多个多义线,包括自交多边形。填充方式非零。" };
            List<ObjectId> ids = sel.Sel(selInfo);
            if (0 == ids.Count) { return; }
            var edit = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptDoubleOptions pdo = new PromptDoubleOptions("请输入需要偏移的距离,非零实数") { DefaultValue = 10 };
            var pdr = edit.GetDouble(pdo);
            if (pdr.Status != PromptStatus.OK) { return; }

          

            JoinType jt = JoinType.Miter;
            {
                PromptKeywordOptions pko = new PromptKeywordOptions(
              "\n拐点类型JoinType。"
          );
                pko.Keywords.Add("Miter", "M", "尖角(斜接)(M)");
                pko.Keywords.Add("Round", "R", "圆角(R)");
                pko.Keywords.Add("Square", "S", "方角(S)");
                pko.Keywords.Add("Bevel", "B", "斜切(B)");
                pko.Keywords.Default = "Miter";
                PromptResult pr = edit.GetKeywords(pko);
                if (pr.Status == PromptStatus.Cancel) { return; }
                if (pr.StringResult == "Round")
                {
                    jt = JoinType.Round;
                }
                else if (pr.StringResult == "Square")
                {
                    jt = JoinType.Square;
                }
                else if (pr.StringResult == "Bevel")
                {
                    jt = JoinType.Bevel;
                }
            }
            EndType et = EndType.Polygon;
            {
                PromptKeywordOptions pko = new PromptKeywordOptions("\n首尾端点类型EndType。");
                pko.Keywords.Add("Polygon", "P", "多边形(M)");
                pko.Keywords.Add("Butt", "B", "平头(B)");
                pko.Keywords.Add("Square", "S", "方头(S)");
                pko.Keywords.Add("Round", "R", "圆头(R)");
                pko.Keywords.Add("Joined", "J", "连接(J)");
                pko.Keywords.Default = "Polygon";
                PromptResult pr = edit.GetKeywords(pko);
                if (pr.Status == PromptStatus.Cancel) { return; }
                if (pr.StringResult == "Joined")
                {
                    et = EndType.Joined;
                }
                else if (pr.StringResult == "Butt")
                {
                    et = EndType.Butt;
                }
                else if (pr.StringResult == "Square")
                {
                    et = EndType.Square;
                }
                else if (pr.StringResult == "Round")
                {
                    et = EndType.Round;
                }
            }

            PathsD ps = new PathsD();
            using (var tr = CadBase.GetDefaultDatabase().TransactionManager.StartTransaction())
            {
                foreach (var id in ids)
                {
                    var pl = tr.GetObject(id, OpenMode.ForWrite) as Polyline;
                    if (null == pl) { continue; }
                    var path = pl.PolylineToPath();
                    ps.Add(path);
                    pl.SetEndWidth10();
                }
                tr.Commit();
            }
            ps = Clipper.Union(ps, FillRule.NonZero);//通过并集避免自相交
            double miterLimit = 4;
           var sol= Clipper.InflatePaths(ps, pdr.Value, jt, et);
            var rect = Clipper.GetBounds(sol);
           // sol = Clipper.TranslatePaths(sol, (long)(rect.Width * 1.2 + 0.5), 0);
            ShowPaths(sol);
        }

演示视频及工具下载

演示工具基于Cad,支持Cad2013及更高版本。

亲士库版本:2026.9.4

Cliper库版本:2.0.0.0

点击下载亲士数学演示工具箱

如果不会操作,请看视频:https://edu.csdn.net/course/detail/41418

扩展阅读

计算几何为骨,排样优化为魂
作品:亲士CAD工具箱
经典文章推荐:二维排样
万物皆数学
查阅鄙人的博文,请点击博文下载学院导航
活到老,学到老。明朝中后期,大约50%的进士能当上堂官(副部及更高);能当上堂官的举人只有十余人。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
HIT_Weston2 天前
7、【数学】【基础】复数是什么:从解方程到旋转
数学·基础
铸人2 天前
再论勾股定理成立的条件-28
数学·几何学·复数·物理
HIT_Weston3 天前
5、【数学】【基础】归一化的几何意义:球面、超平面与信息去哪了
数学·基础
email4u5 天前
当 AI 开始解决数学难题
人工智能·数学
Tisfy7 天前
LeetCode 0836.矩形重叠:xy两方向分别看
数学·leetcode·题解·模拟
闻缺陷则喜何志丹7 天前
【计算几何】布尔运算交并补异或
数学·计算几何·布尔运算·奇偶填充·非零填充·正数填充·负数填充
lisw059 天前
数学系学生如何入门计算基因组学?
数学·计算基因组学
闻缺陷则喜何志丹11 天前
【计算几何】闵可夫斯基差演示
数学·计算几何·autocad·闵可夫斯基差
ClouGence12 天前
老师备课到底能不能交给 AI?我拿鸡兔同笼实测了一遍
数学·aigc