明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 922|回复: 3

[几何] 求一个c#.net合并直线、多段线、圆弧。。。。的方法,类似CAD内置命令“J”,

[复制链接]
发表于 2021-1-21 11:14 | 显示全部楼层 |阅读模式
求一个c#.net合并直线、多段线、圆弧。。。。的方法,类似CAD内置命令“J”,线段的合并想法就是取出所有点,然后排序生成新的多段线。
但是圆弧怎么搞?哪位大神可以指导指导

如果是一个点集合的话,怎么记录哪一段需要转换圆弧,转换的角度怎么记录、一头雾水。
发表于 2021-1-25 14:17 | 显示全部楼层
生成多段线的方式是点集+凸度,自己先写一次生成多段线,了解其中的函数.....
凸度换算的方式参考
http://www.lee-mac.com/bulgeconv ... cetag=s_pcqq_aiomsg
发表于 2021-1-29 10:35 | 显示全部楼层
通过使用.NET分解复杂区域来创建一系列AutoCAD多段线
https://through-the-interface.ty ... reating-a-seri.html
发表于 2021-1-29 14:30 | 显示全部楼层
    /// <summary>
    /// 将Line Arc LWPolyline 编辑成LWPolyline,能连接在一起的连接起来
    /// 要求端点相接
    /// Version : 2007.09.19 Sieben
    /// 2007.11.01有改动,未做详细测试
    /// 2008.02.14 修改封闭曲线时导致出现零节点的问题
    /// </summary>
    /// <param name="cur1">第一曲线,若两条曲线连接成一条,则新曲线使用第一曲线一般属性(有例外),不应该为null</param>
    /// <param name="cur2">第二曲线,可以为null,这时是编辑单个实体</param>
    /// <param name="dTol">一个距离数值,用于作为判断两点重合的标准</param>
    /// <returns>成功返回aPolyline,否则返回null</returns>
    public static aPolyline JoinPolyline(Curve cur1, Curve cur2, double dTol)
    {
      try
      {
        //ae.WriteMessage("\nadb.JoinPolyline start ");
        aPolyline pline = null;
        if (cur1 == null || cur1.Closed) return null;
        if (!cur1.GetType().Equals(typeof(aPolyline)))
        {
          #region !aPolylineine Arc aPolyline
          if (cur2 != null && cur2.GetType().Equals(typeof(aPolyline)))
          {//第一曲线为非aPolyline,而第二曲线为aPolyline,这时以第二曲线作为第一曲线重新调用函数,此举只为减少代码
            return aCur.JoinPolyline(cur2, cur1, dTol);
          }
          pline = new aPolyline();
          if (cur1.GetType().Equals(typeof(Line)))//Line:?
          {//曲线为  Line,使用其数据生成一个aPolyline
            Line line = (Line)cur1;
            pline.AddVertexAt(0, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
            pline.AddVertexAt(1, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
            pline.SetPropertiesFrom(line);//使用原来实体属性
            if (cur2 != null)//若第二曲线不为空,则试图连接两者
              pline = aCur.JoinPolyline(pline, cur2, dTol);
            return pline;//将新生成的多段线提交到数据库
          }
          else if (cur1.GetType().Equals(typeof(Arc)))//Arc:?
          {//曲线为  Line,使用其数据生成一个aPolyline   
            Arc arc = (Arc)cur1;
            Point3d p1 = arc.GetPointAtParameter(arc.EndParam * 0.5 + arc.StartParam * 0.5);
            double dltAng = arc.EndAngle - arc.StartAngle;
            if (dltAng < 0.0) dltAng += aCon.PI360;//圆弧的结束角比开始角大时
            double bulge = Math.Tan(dltAng / 4.0);
            if (ag.Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)//根据圆弧的时钟走向确定凸度正负
              bulge = -bulge;
            pline.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), bulge, 0, 0);
            pline.AddVertexAt(1, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0);
            pline.SetPropertiesFrom(arc);//使用原来实体属性
            if (cur2 != null)//若第二曲线不为空,则试图连接两者
              pline = aCur.JoinPolyline(pline, cur2, dTol);
            return pline;//将新生成的多段线提交到数据库
          }
          else
          {//本函数只处理Line Arc aPolyline 三种类型曲线         
            return null;
          }
          #endregion !aPolylineine Arc aPolyline
        }
        else if (cur1.GetType().Equals(typeof(aPolyline)))
        {
          #region aPolylineine Arc aPolyline

          pline = (aPolyline)cur1;
          if (pline.StartPoint.DistanceTo(pline.EndPoint) < dTol)
          {//曲线的起点和终点重合,将其封闭属性设置为true
            if (!pline.Closed)
              pline.Closed = true;
            return pline;
          }
          if (cur2 != null && cur2.GetType().Equals(typeof(Line)))
          {//第二曲线为Line,将其加入到多段线里,需注意是加入直线的远点
            #region aPolylineine
            Line line = (Line)cur2;
            if (pline.EndPoint.DistanceTo(line.StartPoint) < dTol)
            {
              pline.AddVertexAt(pline.NumberOfVertices, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
            }
            else if (pline.EndPoint.DistanceTo(line.EndPoint) < dTol)
            {
              pline.AddVertexAt(pline.NumberOfVertices, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
            }
            else if (pline.StartPoint.DistanceTo(line.StartPoint) < dTol)
            {
              pline.AddVertexAt(0, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
            }
            else if (pline.StartPoint.DistanceTo(line.EndPoint) < dTol)
            {
              pline.AddVertexAt(0, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
            }
            #endregion aPolylineine
          }
          else if (cur2 != null && cur2.GetType().Equals(typeof(Arc)))
          {
            #region aPolyline:Arc
            //第二曲线为Arc,将其加入到多段线里,需注意凸度的计算及正负
            //凸度的大小由圆弧的圆周角计算可得,
            //凸度的正负先根据圆弧的时钟走向得到一个值,然后在根据圆弧的近点,中点,远点三点的时钟走向
            //还有在aPolyline里是后加入还是前插入来最终确定正负
            Arc arc = (Arc)cur2;
            Point3d p1 = arc.GetPointAtParameter(arc.EndParam * 0.5 + arc.StartParam * 0.5);
            double dltAng = arc.EndAngle - arc.StartAngle;
            if (dltAng < 0.0) dltAng += aCon.PI360;
            double bulge = Math.Tan(dltAng / 4.0);
            if (pline.EndPoint.DistanceTo(arc.StartPoint) < dTol)
            {//末端接入,根据圆弧近点,中点,远点确定凸度正负
              if (ag.Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)
                bulge = -bulge;
              pline.AddVertexAt(pline.NumberOfVertices, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0);
              pline.SetBulgeAt(pline.NumberOfVertices - 2, bulge);//注意凸度段序号
            }
            else if (pline.EndPoint.DistanceTo(arc.EndPoint) < dTol)
            {//末端接入,根据圆弧近点,中点,远点确定凸度正负
              if (ag.Clockwise(arc.EndPoint, p1, arc.StartPoint) == -1)
                bulge = -bulge;
              pline.AddVertexAt(pline.NumberOfVertices, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), 0, 0, 0);
              pline.SetBulgeAt(pline.NumberOfVertices - 2, bulge);
            }
            else if (pline.StartPoint.DistanceTo(arc.StartPoint) < dTol)
            {//开始端接入,根据圆弧远点,中点,近点确定凸度正负
              if (ag.Clockwise(arc.EndPoint, p1, arc.StartPoint) == -1)
                bulge = -bulge;
              pline.AddVertexAt(0, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), bulge, 0, 0);
            }
            else if (pline.StartPoint.DistanceTo(arc.EndPoint) < dTol)
            {//开始端接入,根据圆弧远点,中点,近点确定凸度正负
              if (ag.Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)
                bulge = -bulge;
              pline.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), bulge, 0, 0);
            }
            #endregion aPolyline:Arc
          }
          else if (cur2 != null && cur2.GetType().Equals(typeof(aPolyline)))
          {
            #region aPolyline:aPolyline
            aPolyline pline2 = (aPolyline)cur2;
            if (pline.EndPoint.DistanceTo(pline2.StartPoint) < dTol)
            { //第一曲线末端接入,第二曲线正向加入
              for (int i = 1; i < pline2.NumberOfVertices; i++)//一段段的读出,加入另外曲线
              {
                pline.AddVertexAt(pline.NumberOfVertices, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(pline.NumberOfVertices - 2, pline2.GetBulgeAt(i - 1));//注意凸度段序号
              }
            }
            else if (pline.EndPoint.DistanceTo(pline2.EndPoint) < dTol)
            {//末端接入,第二曲线逆向加入,第二曲线原有凸度需反向
              for (int i = pline2.NumberOfVertices - 2; i >= 0; i--)
              {
                pline.AddVertexAt(pline.NumberOfVertices, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(pline.NumberOfVertices - 2, -pline2.GetBulgeAt(i));
              }
            }
            else if (pline.StartPoint.DistanceTo(pline2.StartPoint) < dTol)
            {
              //第一曲线开始端入,第二曲线逆向加入,第二曲线原有凸度需反向
              for (int i = 1; i < pline2.NumberOfVertices; i++)
              {
                pline.AddVertexAt(0, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(0, -pline2.GetBulgeAt(i - 1));
              }
            }
            else if (pline.StartPoint.DistanceTo(pline2.EndPoint) < dTol)
            {
              //第一曲线开始端入,第二曲线正向加入
              for (int i = pline2.NumberOfVertices - 2; i >= 0; i--)
              {
                pline.AddVertexAt(0, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(0, pline2.GetBulgeAt(i));
              }
            }
            #endregion aPolyline:aPolyline
          }
          else
          {
            return null;
          }
          if (pline.StartPoint.DistanceTo(pline.EndPoint) < dTol) //如果曲线起点和终点重合,将Closed = true
          {
            pline.Closed = true;
            //2008.02.14注意:即使起点和终点已重合,pline.Closed = true还是会增加一个节点,导致多段线出现零节点
            pline.RemoveVertexAt(pline.NumberOfVertices - 1);
          }
          return pline;
          #endregion aPolylineine Arc aPolyline
        }
        return pline;
      }
      catch (System.Exception ex)
      {
        ae.WriteMessage(ex);
        return null;
      }
    }

非不想分享全部,但涉及的代码太多了,没有时间。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-27 15:19 , Processed in 0.190263 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表