a393006410 发表于 2021-1-21 11:14:16

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

求一个c#.net合并直线、多段线、圆弧。。。。的方法,类似CAD内置命令“J”,线段的合并想法就是取出所有点,然后排序生成新的多段线。
但是圆弧怎么搞?哪位大神可以指导指导

如果是一个点集合的话,怎么记录哪一段需要转换圆弧,转换的角度怎么记录、一头雾水。

你有种再说一遍 发表于 2021-1-25 14:17:52

生成多段线的方式是点集+凸度,自己先写一次生成多段线,了解其中的函数.....
凸度换算的方式参考
http://www.lee-mac.com/bulgeconversion.html?tdsourcetag=s_pcqq_aiomsg

zjy2999 发表于 2021-1-29 10:35:27

通过使用.NET分解复杂区域来创建一系列AutoCAD多段线
https://through-the-interface.typepad.com/through_the_interface/2008/08/creating-a-seri.html

sieben 发表于 2021-1-29 14:30:56

    /// <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 !aPolyline:Line 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 !aPolyline:Line Arc aPolyline
      }
      else if (cur1.GetType().Equals(typeof(aPolyline)))
      {
          #region aPolyline:Line 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 aPolyline:Line
            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 aPolyline:Line
          }
          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 aPolyline:Line Arc aPolyline
      }
      return pline;
      }
      catch (System.Exception ex)
      {
      ae.WriteMessage(ex);
      return null;
      }
    }

非不想分享全部,但涉及的代码太多了,没有时间。
页: [1]
查看完整版本: 求一个c#.net合并直线、多段线、圆弧。。。。的方法,类似CAD内置命令“J”,