• cad.net 投影三维图元到某个平面上+求图元交点


    投影三维图元到某个平面上

    如果遇到复杂的三维图元,要先进行消隐hide命令,但是我还没研究好这个命令.

    红色(1号色)是三维的,黄色(2号色)投影下来的,它是曲线,因为曲线是直线的父类.可以依照曲率转换为自己喜欢的直线或者多段线,圆弧等等.
    image

    命令

    [CommandMethod("test_ty", CommandFlags.Modal | CommandFlags.Session | CommandFlags.Redraw)]
    public static void JJ_testty()
    {
        Database db = HostApplicationServices.WorkingDatabase;//当前的数据库
        Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
        ed.WriteMessage("
    ****{惊惊连盒}测试,投影三维图元到某个平面上");
    
        using (Acap.DocumentManager.MdiActiveDocument.LockDocument())//锁文档 CommandFlags.Session
        {
            db.Action(tr =>
            {
                //三维的线 
                var entity = new Line(Point3d.Origin, new Point3d(1, 1, 1));//var entity = EntityAdd.AddLineToEntity(Point3d.Origin, new Point3d(1, 1, 1));
                entity.ColorIndex = 1;
                var lineId = tr.AddEntityToMsPs(db, entity);
    
                var ids = new List<ObjectId>() { lineId };
                var cus = tr.Entitys2Plane(ids);
                foreach (var item in cus)
                {
                    item.ColorIndex = 2;
                    tr.AddEntityToMsPs(db, item);
                }
            });
        }
    }
    

    投影平面

    /// <summary>
    /// 投影平面
    /// </summary> 
    /// <param name="tr">事务</param>
    /// <param name="ids">图元</param>
    /// <param name="normal">投影方向</param>
    /// <returns>投影到某个平面的图元</returns>
    public static List<Curve> Entitys2Plane(this Transaction tr,
        IEnumerable<ObjectId> ids, Vector3d? normal = null)
    {
        var ls = new List<Curve>();
        if (normal == null)
        {
            normal = Vector3d.ZAxis;//绕Z轴,也就是XY平面
        }
        var plane = new Plane(Point3d.Origin, normal.Value);
        foreach (var sobject in ids)
        {
            if (sobject.IsOk())
            {
                var curve = sobject.ToEntity(tr) as Curve;
                if (curve == null)
                    continue;
                Curve pCurve = null;
                try
                {
                    pCurve = curve.GetOrthoProjectedCurve(plane);
                }
                catch
                { }
                if (pCurve == null)
                    continue; 
                ls.Add(pCurve);
            }
        }
        return ls;
    }
    
    /// <summary>
    /// 将图形添加到数据库的当前空间中
    /// </summary>
    /// <param name="db">图形数据库</param>
    /// <param name="ent">图形对象</param>
    /// <returns>图形的ObjectId</returns>
    public static ObjectId AddEntityToMsPs(this Transaction tr, Database db, Entity ent)
    {
        ObjectId entId;
        //在位编辑的时候自动加到块内了,而不是模型空间,因为会把临时的数据拷贝回去块表记录上面
        //出现eLockViolation 是因 CommandFlags.Session | CommandFlags.Redraw 又没有锁文档
        var btRec = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
        //加图元到块表记录,设定返回值
        entId = btRec.AppendEntity(ent);
        //更新数据
        tr.AddNewlyCreatedDBObject(ent, true);
        btRec.DowngradeOpen();
        btRec.Dispose();
        return entId;
    }
    

    求直线交点

    数学篇 求两条直线的交点,说明过程 中有一个纯数学的解决方法.
    那么cad的图元上面也有一个:Entity.IntersectWith函数.
    但是展示这个函数前需要先说明一下,这个函数遇到两个坐标值特别大的图元会计算不出来,
    例如两条spl样条曲线会计算不出来,而特大的坐标的直线却可以计算,原因可能是内部求导函数的问题.

    Acad2008复现问题的方法是:画pline,设置坐标:(内存长度) (1e15,1e15) ~ (2e15,2e15)~ (3e15,3e15)
    然后在这个范围上画spl,你会发现画得断断续续的...甚至卡死你的cad

    而当你求不出交点的时候要注意是否小数点后数字过多!
    如果遇到不妨将两条spl平移回原点附近再进行求交.

    #if !HC2020
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.Runtime;
    using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
    #else
    using GrxCAD.DatabaseServices;
    using GrxCAD.EditorInput;
    using GrxCAD.Geometry;
    using GrxCAD.ApplicationServices;
    using GrxCAD.DatabaseServices.Filters;
    using GrxCAD.Runtime;
    using Acap = GrxCAD.ApplicationServices.Application;
    #endif
    
    #if AC2008 || AC2010 || AC2012
    using Autodesk.AutoCAD.Interop;
    #endif
    
    namespace JoinBox
    {
        public class Intersection
        {
            [CommandMethod("IntersectionTest")]
            public void IntersectionTest()
            {
                var ed = Acap.DocumentManager.MdiActiveDocument.Editor;
                var db = HostApplicationServices.WorkingDatabase;
                ed.WriteMessage("
    求空间两曲线交点");
    
                var per = ed.GetEntity("
    选择第一条曲线(可以选择line,因为父类是曲线):");
                if (per.Status != PromptStatus.OK) { return; }
                ObjectId id1 = per.ObjectId;
    
                per = ed.GetEntity("
    选择第二条曲线(可以选择line,因为父类是曲线):");
                if (per.Status != PromptStatus.OK) { return; }
                ObjectId id2 = per.ObjectId;
    
                db.Action(tr =>
                {
                    var cur1 = id1.ToEntity(tr) as Curve;
                    var cur2 = id2.ToEntity(tr) as Curve;
    
                    var ints = new Point3dCollection();
    
                   //plane是投影面
                    cur1.IntersectWith(cur2, Intersect.OnBothOperands, new Plane(), ints, 0, 0); //得出的所有交点在c1曲线上
                    if (ints.Count == 0)
                    {
                        ed.WriteMessage($"
    无交点或图元交点过大(小数点过多)");
                    }
                    else
                    {
                        foreach (Point3d pt in ints)
                        {
                            ed.WriteMessage($"
    第一条曲线与第二条曲线交点:{pt}");
                        }
                    }
    
                    ed.WriteMessage("
    ================================================");
                    ints.Clear();
    
                    cur2.IntersectWith(cur1, Intersect.OnBothOperands, new Plane(), ints, 0, 0); //得出的所有交点在c2曲线上
                    if (ints.Count == 0)
                    {
                        ed.WriteMessage($"
    无交点或图元交点过大(小数点过多)");
                    }
                    else
                    {
                        foreach (Point3d pt in ints)
                        {
                            ed.WriteMessage($"
    第二条曲线与第条曲线一交点:{pt}");
                        }
                    }
                });
            }
        }
    }
    

    (完)

  • 相关阅读:
    R语言修改vector、matrix、dataframe列名
    R语言获取数据框的行数
    R语言的which函数,针对没有符合条件的返回值为integer(0),之后如何判断
    ArrayList总结
    经常涉及到的技术
    今天开始写博客啦!(测试..)
    [摘转] JS 数组合并问题
    t_category
    在 MySql 的 update 语句中使用 case when else end
    JSP 取当前时间
  • 原文地址:https://www.cnblogs.com/JJBox/p/14594376.html
Copyright © 2020-2023  润新知