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("\n****{驚驚連盒}測試,投影三維圖元到某個平面上");

    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("\n求空間兩曲線交點");

            var per = ed.GetEntity("\n選擇第一條曲線(可以選擇line,因為父類是曲線):");
            if (per.Status != PromptStatus.OK) { return; }
            ObjectId id1 = per.ObjectId;

            per = ed.GetEntity("\n選擇第二條曲線(可以選擇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($"\n無交點或圖元交點過大(小數點過多)");
                }
                else
                {
                    foreach (Point3d pt in ints)
                    {
                        ed.WriteMessage($"\n第一條曲線與第二條曲線交點:{pt}");
                    }
                }

                ed.WriteMessage("\n================================================");
                ints.Clear();

                cur2.IntersectWith(cur1, Intersect.OnBothOperands, new Plane(), ints, 0, 0); //得出的所有交點在c2曲線上
                if (ints.Count == 0)
                {
                    ed.WriteMessage($"\n無交點或圖元交點過大(小數點過多)");
                }
                else
                {
                    foreach (Point3d pt in ints)
                    {
                        ed.WriteMessage($"\n第二條曲線與第條曲線一交點:{pt}");
                    }
                }
            });
        }
    }
}

子函數

db.Action

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM