其他分享
首页 > 其他分享> > CAD二次开发 学习笔记(2)

CAD二次开发 学习笔记(2)

作者:互联网

 CAD二次开发 学习笔记(2)

 

 

三点法画圆的预备知识(点径法和两点法相对比较简单,不作详述):

思路:

两个点向式方程

联立求出圆心坐标表达式

注意事项:

上述表达式中,分母可能为0;

如果圆的平面在XY平面,那么z坐标表达式的分母则为0,会导致错误;

有两种解决方案(等效的):

方案一:

在使用坐标表达式之前对分母进行判定,如果分母为0,则表示该坐标为0,而不用调用坐标表达式;

方案二:

使用圆所在平面的法向量进行判定,如果法向量的x,y坐标都是0,说明圆所在平面为xy平面,那么z就可以直接赋值0,而不用调用坐标表达式;

 

三种画圆的方法及其实现


        [CommandMethod("circleTest")]
        public void CircleTest()
        {

            Database db = HostApplicationServices.WorkingDatabase;


            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                //点径法创建圆
                Point3d center = new Point3d(10, 10, 0);
                Circle circle1 = CreatCircle(center, 30);
                circle1.ColorIndex = 1;
                DBPoint dbCenter = new DBPoint(center);
                btr.AppendEntity(circle1);
                tr.AddNewlyCreatedDBObject(circle1, true);
                btr.AppendEntity(dbCenter);
                tr.AddNewlyCreatedDBObject(dbCenter, true);
                //两点法创建圆
                Point3d point1 = new Point3d(300, 300, 0);
                Point3d point2 = new Point3d(200, 200, 0);
                DBPoint dbPoint1 = new DBPoint(point1);
                DBPoint dbPoint2 = new DBPoint(point2);
                Circle circle2 = CreatCircle(point1, point2);
                circle2.ColorIndex = 2;
                btr.AppendEntity(circle2);
                tr.AddNewlyCreatedDBObject(circle2, true);
                btr.AppendEntity(dbPoint1);
                tr.AddNewlyCreatedDBObject(dbPoint1, true);
                btr.AppendEntity(dbPoint2);
                tr.AddNewlyCreatedDBObject(dbPoint2, true);

                //三点法创建圆
                Point3d p1 = new Point3d(100, 0, 0);
                Point3d p2 = new Point3d(200, 0, 0);
                Point3d p3 = new Point3d(100, 100, 0);
                DBPoint dbP1 = new DBPoint(p1);
                DBPoint dbP2 = new DBPoint(p2);
                DBPoint dbP3 = new DBPoint(p3);
                Circle circle3 = CreatCircle(p1, p2, p3);
                circle3.ColorIndex = 3;
                btr.AppendEntity(circle3);
                tr.AddNewlyCreatedDBObject(circle3, true);
                btr.AppendEntity(dbP1);
                tr.AddNewlyCreatedDBObject(dbP1, true);
                btr.AppendEntity(dbP2);
                tr.AddNewlyCreatedDBObject(dbP2, true);
                btr.AppendEntity(dbP3);
                tr.AddNewlyCreatedDBObject(dbP3, true);

                db.Pdmode = 34;
                db.Pdsize = 1;
                tr.Commit();
            }
        }
        //点径法创建圆
        public Circle CreatCircle(Point3d center, double radius)
        {
            return new Circle(center, Vector3d.ZAxis, radius);
        }
        //两点法创建圆
        public Circle CreatCircle(Point3d point1, Point3d point2)
        {
            Point3d center = MiddlePoint(point1, point2);
            double radius = center.DistanceTo(point2);
            return new Circle(center, Vector3d.ZAxis, radius);
        }
        //三点法创建圆
        public Circle CreatCircle(Point3d point1, Point3d point2, Point3d point3)
        {
            if (IsCollinear(point1, point2, point3)) return new Circle();
            Vector3d v1 = point1.GetVectorTo(point2);
            Vector3d v2 = point2.GetVectorTo(point3);
            Vector3d n = v1.CrossProduct(v2);
            Point3d p1 = MiddlePoint(point1, point2);
            Point3d p2 = MiddlePoint(point2, point3);
            Vector3d n1 = v1.CrossProduct(n);
            Vector3d n2 = v2.CrossProduct(n);
            double x = Math.Abs(n1.Y * n2.X - n2.Y * n1.X) < 0.000001 ? 0 : (p2.Y * n1.X * n2.X - p1.Y * n1.X * n2.X + p1.X * n1.Y * n2.X - p2.X * n2.Y * n1.X) / (n1.Y * n2.X - n2.Y * n1.X);
            double y = Math.Abs(n1.X * n2.Y - n2.X * n1.Y) < 0.000001 ? 0 : (p2.X * n1.Y * n2.Y - p1.X * n1.Y * n2.Y + p1.Y * n1.X * n2.Y - p2.Y * n2.X * n1.Y) / (n1.X * n2.Y - n2.X * n1.Y);
            double z = Math.Abs(n1.Y * n2.Z - n2.Y * n1.Z) < 0.000001 ? 0 : (p2.Y * n1.Z * n2.Z - p1.Y * n1.Z * n2.Z + p1.Z * n1.Y * n2.Z - p2.Z * n2.Y * n1.Z) / (n1.Y * n2.Z - n2.Y * n1.Z);
            Point3d center = new Point3d(x, y, z);
            double radius = point1.DistanceTo(center);
            return new Circle(center, Vector3d.ZAxis, radius);
        }


        //判断三点是否共线
        public bool IsCollinear(Point3d point1, Point3d point2, Point3d point3)
        {
            Vector3d vector1 = point1.GetVectorTo(point2);
            Vector3d vector2 = point2.GetVectorTo(point3);
            double angle = vector1.GetAngleTo(vector2);
            if (Math.Abs(angle) < 0.0001 || Math.Abs(angle - Math.PI) < 0.000001) return true;
            return false;
        }
        //求两点的中点
        public Point3d MiddlePoint(Point3d point1, Point3d point2)
        {
            return new Point3d((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2, (point1.Z + point2.Z) / 2);
        }

运行结果

角度测试

 [CommandMethod("AngleTest")]
        public void AngleTest()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            ed.WriteMessage($"Vector3d.XAxis.GetAngleTo(Vector3d.YAxis):{Vector3d.XAxis.GetAngleTo(Vector3d.YAxis)}\n");
            ed.WriteMessage($"Vector3d.XAxis.GetAngleTo(Vector3d.YAxis):{Vector3d.XAxis.GetAngleTo(Vector3d.YAxis) * 180 / Math.PI}\n");
            ed.WriteMessage($"Vector3d.XAxis.GetAngleTo(-Vector3d.YAxis):{Vector3d.XAxis.GetAngleTo(-Vector3d.YAxis)}\n");
            ed.WriteMessage($"Vector3d.XAxis.GetAngleTo(-Vector3d.YAxis):{Vector3d.XAxis.GetAngleTo(-Vector3d.YAxis) * 180 / Math.PI}\n");

            ed.WriteMessage($"new Vector3d(1,1,0).GetAngleTo(Vector3d.XAxis):{new Vector3d(1, 1, 0).GetAngleTo(Vector3d.XAxis)}\n");
            ed.WriteMessage($"new Vector3d(1,1,0).GetAngleTo(Vector3d.XAxis):{new Vector3d(1, 1, 0).GetAngleTo(Vector3d.XAxis) * 180 / Math.PI}\n");
            ed.WriteMessage($"new Vector3d(1,1,0).GetAngleTo(-Vector3d.XAxis):{new Vector3d(1, 1, 0).GetAngleTo(-Vector3d.XAxis)}\n");
            ed.WriteMessage($"new Vector3d(1,1,0).GetAngleTo(-Vector3d.XAxis):{new Vector3d(1, 1, 0).GetAngleTo(-Vector3d.XAxis) * 180 / Math.PI}\n");

            ed.WriteMessage($"new Vector3d(1, 1, 0).GetAngleTo(Vector3d.YAxis):{new Vector3d(1, 1, 0).GetAngleTo(Vector3d.YAxis)}\n");
            ed.WriteMessage($"new Vector3d(1, 1, 0).GetAngleTo(Vector3d.YAxis):{new Vector3d(1, 1, 0).GetAngleTo(Vector3d.YAxis) * 180 / Math.PI}\n");
            ed.WriteMessage($"new Vector3d(1, 1, 0).GetAngleTo(-Vector3d.YAxis):{new Vector3d(1, 1, 0).GetAngleTo(-Vector3d.YAxis)}\n");
            ed.WriteMessage($"new Vector3d(1, 1, 0).GetAngleTo(-Vector3d.YAxis):{new Vector3d(1, 1, 0).GetAngleTo(-Vector3d.YAxis) * 180 / Math.PI}\n");
        }

运行结果

 

标签:Vector3d,GetAngleTo,笔记,n1,二次开发,new,n2,Point3d,CAD
来源: https://www.cnblogs.com/zhangdezhang/p/16183266.html