天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 54|回复: 0

ObjectARX2015 + vs2012创建圆

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
[code]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);
    }

原文链接:https://blog.csdn.net/qq_42981953/article/details/121794320[/code]

 

 

 

 

ObjectARX2015 + vs2012创建圆
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 11:40 , Processed in 0.122409 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表