Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

带状地形图,根据多段线,生成A3的图框 #44

Open
topcss opened this issue Sep 12, 2019 · 0 comments
Open

带状地形图,根据多段线,生成A3的图框 #44

topcss opened this issue Sep 12, 2019 · 0 comments
Labels

Comments

@topcss
Copy link
Owner

topcss commented Sep 12, 2019

带状地形图,根据多段线,生成A3的图框

// Standard .NET namespaces
using System;
using System.Collections.Generic;

// Main AutoCAD namespaces
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Dreambuild.AutoCAD;

[assembly: CommandClass(typeof(Sample.App))]
namespace Sample
{
    public class App
    {
        /// <summary>
        /// 生成:图框
        /// 线路生成斜框
        /// </summary>
        [CommandMethod("tk")]
        public void Xlscxk()
        {
            var id = Interaction.GetEntity("\n请选择道路中心线:", typeof(Polyline));
            if (id == ObjectId.Null)
            {
                Interaction.WriteLine("您取消了选择。");
                return;
            }

            // 定义A3的尺寸。长 a 宽 b
            double a = 420, b = 297;
            // 定义起点
            Point2d ps = Point2d.Origin;
            ObjectId pid = ObjectId.Null;
            // 第几个图框
            int index = 1;

            // 工具 id 读取对象
            var poly = id.QOpenForRead<Polyline>();
            // 遍历对象
            for (int i = 0; i <= poly.EndParam; i++)
            {
                var pe = poly.GetPoint2dAt(i);
                if (ps != Point2d.Origin)
                {
                    // 如果点在上一个多边形中,就跳过
                    if (!ObjectId.Null.Equals(pid))
                    {
                        var pl = pid.QOpenForRead<Polyline>();
                        if (pl.IsPointIn(pe.ToPoint3d()))
                        {
                            ps = pe;
                            continue;
                        }
                    }

                    //; 计算两个点之间的 x 轴的夹角
                    var alpha = ps.GetVectorTo(pe).Angle;
                    //; 计算两个点之间的距离
                    var dstc = ps.GetDistanceTo(pe);
                    //; 定义 nn 循环的个数
                    var nn = Math.Ceiling(dstc / a);

                    var pa = PolarPoints(ps, alpha + Math.PI / 2, b / 2);
                    for (int j = 0; j < nn; j++)
                    {
                        var pb = PolarPoints(pa, alpha, a);
                        var pc = PolarPoints(pa, alpha - Math.PI / 2, b);
                        var pd = PolarPoints(pc, alpha, a);

                        pid = Draw.Pline(new List<Point3d>
                        {
                            pa.ToPoint3d(),
                            pb.ToPoint3d(),
                            pd.ToPoint3d(),
                            pc.ToPoint3d(),
                            pa.ToPoint3d()
                        });
                        // 把对象放到 图框图层中
                        pid.SetLayer("tkLayer");

                        index++;

                        // 重新计算起点
                        pa = PolarPoints(pa, alpha, a);
                    }
                }

                ps = pe;
            }
        }

        private readonly Document _doc = Application.DocumentManager.MdiActiveDocument;
        private string layoutName = "TestLayout";


        static Point2d PolarPoints(Point2d pPt, double dAng, double dDist)
        {
            return new Point2d(pPt.X + dDist * Math.Cos(dAng),
                pPt.Y + dDist * Math.Sin(dAng));
        }

        static Point3d PolarPoints(Point3d pPt, double dAng, double dDist)
        {
            return new Point3d(pPt.X + dDist * Math.Cos(dAng),
                pPt.Y + dDist * Math.Sin(dAng),
                pPt.Z);
        }

        private void CreateLayout()
        {
            // 创建布局
            var layout = LayoutManager.Current.CreateLayout(layoutName).QOpenForRead<Layout>();
            Interaction.WriteLine($"创建布局 {layout.LayoutName} 成功!");

            // 切换布局,目的是激活
            LayoutManager.Current.CurrentLayout = layoutName;
        }

        private Viewport GetViewport(int n)
        {
            // 每行几个
            var numPerline = 5m;
            // 计算行号
            var rowNum = (double)Math.Ceiling(n / numPerline);
            // 计算列号
            var colNum = Math.Ceiling(n % numPerline) != 0m
                ? (double)Math.Ceiling(n % numPerline)
                : (double)numPerline;

            //  定义:长、宽、间隔
            double a = 285, b = 200, c = 50;

            //// 可用的左上方原点坐标
            double orginX = -1400, orginY = 600;

            double cx = orginX + a / 2 +
                        // 第几列
                        ((a + c) * (colNum - 1)); ;
            double cy = orginY - b / 2 -
                        // 第几行
                        ((b + c) * (rowNum - 1)); ;

            //创建视口
            Viewport vp = new Viewport
            {
                CenterPoint = new Point3d(cx, cy, 0),
                Width = a,
                Height = b
            };

            return vp;
        }


        /// </summary>
        [CommandMethod("bj")]
        async public void bj()
        {
            CreateLayout();

            // 切换到Paper空间布局
            Application.SetSystemVariable("TILEMODE", 0);
            _doc.Editor.SwitchToPaperSpace();

            Database acCurDB = _doc.Database;
            using (Transaction acTrans = acCurDB.TransactionManager.StartTransaction())
            {
                LayerTable layertb = acTrans.GetObject(acCurDB.LayerTableId, OpenMode.ForRead) as LayerTable;
                LayerTableRecord lyrbRecord = acTrans.GetObject(layertb["tkLayer"], OpenMode.ForWrite) as LayerTableRecord;

                // 图框
                List<Entity> tkList = new List<Entity>();

                //以读模式打开块表
                BlockTable bt = acTrans.GetObject(acCurDB.BlockTableId, OpenMode.ForRead) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btRecord = acTrans.GetObject(btrid, OpenMode.ForRead) as BlockTableRecord;
                    foreach (ObjectId eid in btRecord)  //遍历块表记录
                    {
                        Entity ent = acTrans.GetObject(eid, OpenMode.ForRead) as Entity;
                        if (ent != null && ent.LayerId == lyrbRecord.ObjectId)
                        {
                            tkList.Add(ent);
                        }
                    }
                }

                //以写模式打开块表记录Paper空间
                BlockTableRecord acBlkTbRecord = acTrans.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForWrite) as BlockTableRecord;
                Viewport vp;
                for (int i = 0; i < tkList.Count; i++)
                {
                    Polyline pl = tkList[i] as Polyline;

                    vp = GetViewport(i + 1);  //创建一个视口对象

                    // 添加新对象到块表记录和事务
                    acBlkTbRecord.AppendEntity(vp);
                    acTrans.AddNewlyCreatedDBObject(vp, true);

                    // 注意:旋转必须在加入到块表中才能生效。
                    // 计算线框的起点
                    var p1 = pl.GetPoint2dAt(0);
                    var p2 = pl.GetPoint2dAt(1);
                    var p3 = pl.GetPoint2dAt(2);
                    var p4 = pl.GetPoint2dAt(3);

                    // 计算平移
                    var pMin = pl.GeometricExtents.MinPoint;
                    var pMax = pl.GeometricExtents.MaxPoint;

                    // 中心点为对角线
                    var pCenter = new Point3d((p1.X + p3.X) / 2, (p1.Y + p3.Y) / 2, 0);

                    var width = p1.GetDistanceTo(p2);
                    var height = p2.GetDistanceTo(p3);

                    vp.UpgradeOpen();
                    vp.Visible = true;
                    vp.GridOn = true;

                    // 激活
                    vp.On = true;

                    // angle 是弧度
                    var alpha = (360 - p1.GetVectorTo(p2).Angle * (180 / Math.PI)) * (Math.PI / 180);
                    vp.TwistAngle = alpha;

                    // 设置中心点和高度,确定框的大小和位置 
                    vp.ViewCenter = pCenter.ToPoint2d().TransformBy(Matrix2d.Rotation(alpha, Point2d.Origin));
                    vp.ViewHeight = height;

                    Interaction.WriteLine($"{i + 1}: {p1.X},{p1.Y} {p3.X},{p3.Y}");

                    vp.DowngradeOpen();
                    vp.UpdateDisplay();

                    _doc.Editor.UpdateScreen();
                }

                acTrans.Commit();
            }
        }
    }
}
@topcss topcss added the 🔪C# label Sep 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant