(5)ObjectARX2015 + vs2012创建圆

提示:看之前的博客(1)和(4),那里已经分析了创建一个图形对象的基本过程,在之前的基础上本节开始就要将着眼点放在创建实体的参数上。

(1)ObjectARX2015 + vs2012创建直线_qq_42981953的博客-CSDN博客

(4)ObjectARX2015 + vs2012扩展绘制直线的功能为绘制实体_qq_42981953的博客-CSDN博客

1. 说明

本节的实例分别用“圆心、半径”、“直径的两个端点”和“三点法”创建圆。(三种方式)。

2. 思路

ObjectARX 中, AcDbCircle 类用来表示圆。该类有两个构造函数,其形式分别为:
AcDbCircle(); 
AcDbCircle(const AcGePoint3d& cntr, const AcGeVector3d& nrm, double radius);

//两个构造函数的名称相同,接受不同的参数,这是 C++中函数的重载。
//重载是 C++提供的一个很有用的特性,相同功能的函数采用同样的名称,大大减少了程序员的记忆量。
//创建一个圆需要三个参数:圆心、半径和圆所在的平面(一般用平面的法向量来表示)。

//第一个构造函数不接受任何参数,创建一个圆心为(0,0,0)、半径为0的圆,其所在平面法
向量为(0,0,1);
//第二个构造函数则接受了圆心、圆所在平面法向量和半径三个参数。
//一般来说,我习惯于在创建实体时直接将其初始化,很少用第一个构造函数。

3. 步骤

(1)//创建圆(中心点, 圆所在平面, 半径)

    //创建圆(中心点, 圆所在平面, 半径)
    static AcDbObjectId CreateCircle(AcGePoint3d centerPoint, AcGeVector3d normal, double radius);	//创建圆(中心点, 圆所在平面, 半径)
//创建圆(中心点, 圆所在平面, 半径)
AcDbObjectId CCreateEnt::CreateCircle(AcGePoint3d centerPoint, AcGeVector3d normal, double radius)
{
    AcDbCircle *pCircle = new AcDbCircle(centerPoint, normal, radius);
    AcDbObjectId circleId;
    circleId = CCreateEnt::PostToModelSpace(pCircle);

    return circleId;
}

(2)//创建在XOY平面上的圆(中心点, 半径)

//创建在XOY平面上的圆(中心点, 半径)
static AcDbObjectId CreateCircle(AcGePoint3d centerPoint, double radius);	
//创建在XOY平面上的圆(中心点, 半径)
AcDbObjectId CCreateEnt::CreateCircle(AcGePoint3d centerPoint, double radius)
{
    AcGeVector3d vec(0, 0, 1);
    return CreateCircle(centerPoint, vec, radius);
}

(3)//创建圆两点法(起点, 结束点)

先创建一个CGeometryOper新类:用于封装计算的相关函数。添加两个重载静态函数MiddlePoint,用于计算两点连线的中点:

// GeometryOper.h

    //获取中间点(三维)
    AcGePoint3d GetMiddlePoint(AcGePoint3d startPoint, AcGePoint3d endPoint);
    //获取中间点(二维)
    AcGePoint2d GetMiddlePoint(AcGePoint2d startPoint, AcGePoint2d endPoint);

// GeometryOper.cpp

//获取中间点(三维)
AcGePoint3d CGeometryOper::GetMiddlePoint(AcGePoint3d startPoint, AcGePoint3d endPoint)
{
    double x = (startPoint.x, endPoint.x) * 0.5;
    double y = (startPoint.y, endPoint.y) * 0.5;
    double z = (startPoint.z, endPoint.z) * 0.5;
    return AcGePoint3d(x, y, z);
}

//获取中间点(二维)
AcGePoint2d CGeometryOper::GetMiddlePoint(AcGePoint2d startPoint, AcGePoint2d endPoint)
{
    double x = (startPoint.x, endPoint.x) * 0.5;
    double y = (startPoint.y, endPoint.y) * 0.5;
    return AcGePoint2d(x, y);
}

//创建圆两点法(起点, 结束点)

//创建圆两点法(起点, 结束点)
AcDbObjectId CCreateEnt::CreateCircle(AcGePoint2d startPoint, AcGePoint2d endPoint)
{
    //计算半径和圆心
//     CGeometryOper m_geometryOper;
//     AcGePoint2d center2d = m_geometryOper.GetMiddlePoint(startPoint, endPoint);
//     AcGePoint3d center3d(center2d.x, center2d.y, 0);
//     double radius = center3d.distanceTo(startPoint);
// 
//     return CreateCircle(center3d, radius);
    return 0;
}

(4)// 创建圆三点法 (起点, 第二点, 结束点)

    //创建圆(中心点, 圆所在平面, 半径)
    static AcDbObjectId CreateCircle(AcGePoint2d Point1, AcGePoint2d Point2, AcGePoint2d Point3);
//创建圆三点法(起点, 第二点, 结束点)
AcDbObjectId CCreateEnt::CreateCircle(AcGePoint2d Point1, AcGePoint2d Point2, AcGePoint2d Point3)
{
    //使用数学方法
    double xysm = 0, xyse = 0, xy = 0;
    AcGePoint3d ptCenter;
    double radius = 0;

    //pow(double x, double y) 返回 x 的 y 次幂
    xy = pow(Point1.x, 2) + pow(Point1.y, 2);
    xyse = xy - pow(Point3.x, 2) - pow(Point3.y, 2);
    xysm = xy - pow(Point2.x, 2) - pow(Point2.y, 2);
    xy = (Point1.x - Point2.x) * (Point1.y - Point2.y) - (Point1.x - Point3.x) * (Point1.y - Point3.y);

    //判断参考有效性
    //fabs 获得数的绝对值
    if (fabs(xy) < 0.000001)
    {
        AfxMessageBox(_T("所输入的参数无法创建圆形"));
        return AcDbObjectId::kNull;
    }

    //获得圆心和半径
    ptCenter.x = (xysm * (Point1.y - Point3.y) - xyse * (Point1.y - Point2.y) / (2 * xy));
    ptCenter.y = (xyse * (Point1.y - Point2.y) - xysm * (Point1.y - Point3.y) / (2 * xy));
    ptCenter.z = 0;

    //sqrt 开平方
    radius = sqrt(Point1.x - ptCenter.x) * (Point1.x - ptCenter.x) + (Point1.y - ptCenter.y) * (Point1.y - ptCenter.y);

    if (radius < 0.000001)
    {
        AfxMessageBox(_T("半径过小"));
        return AcDbObjectId::kNull;
    }

    return CreateCircle(ptCenter, radius);
}

(6)在acrxEntryPoint.cpp中添加#include "CreateCircle.h"头文件后添加注册命令

ACED_ARXCOMMAND_ENTRY_AUTO(CArxConfigApp, MidasMyGroup, MyDrawCircle, MyDrawCircle, ACRX_CMD_MODAL, NULL) //画圆
    //当前项目中注册一个命令 AddCircle
    static void MidasMyGroupMyDrawCircle() 
    { 
        AcGePoint3d ptStart(0, 0, 0); 
        double radius = 10; 
        AcDbObjectId circleId; 
        circleId = CCreateEnt::CreateCircle(ptStart, radius);
        CModifyEnt m_modifyEnt;
        m_modifyEnt.ChangeColor(circleId, 1);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值