首先看一下效果圖:數據庫
分爲4部分,先看代碼最少的計算模塊:app
**********Calculation.h******************* #pragma once class sAcGePoint2d; class AcGePoint3d; class CCalculation { public: CCalculation(void); ~CCalculation(void); //計算兩點連線的中點 static AcGePoint2d MiddlePoint(AcGePoint2d pt1, AcGePoint2d pt2); static AcGePoint3d MiddlePoint(AcGePoint3d pt1, AcGePoint3d pt2); static AcGePoint3d Pt2dTo3d(AcGePoint2d pt); //計算常量π的值 static double PI(); };
**********Calculation.cpp******************* #include "StdAfx.h" #include "Calculation.h" #include <math.h> CCalculation::CCalculation(void) { } CCalculation::~CCalculation(void) { } AcGePoint2d CCalculation::MiddlePoint(AcGePoint2d pt1, AcGePoint2d pt2) { AcGePoint2d pt; pt[X] = (pt1[X] + pt2[X]) / 2; pt[Y] = (pt1[Y] + pt2[Y]) / 2; return pt; } AcGePoint3d CCalculation::MiddlePoint(AcGePoint3d pt1, AcGePoint3d pt2) { AcGePoint3d pt; pt[X] = (pt1[X] + pt2[X]) / 2; pt[Y] = (pt1[Y] + pt2[Y]) / 2; pt[Z] = (pt1[Z] + pt2[Z]) / 2; return pt; } AcGePoint3d CCalculation::Pt2dTo3d(AcGePoint2d pt) { AcGePoint3d ptTemp(pt.x, pt.y, 0); return ptTemp; } double CCalculation::PI() { return 4 * atan(1.0);//反正切 }
而後咱們看一下,修改顏色,圖層,線條:函數
**********CModifyEnt.h******************* #pragma once #include "StdAfx.h" class CModifyEnt { public: CModifyEnt(void); ~CModifyEnt(void); //改變顏色 static Acad::ErrorStatus ChangeColor(AcDbObjectId entId, Adesk::UInt16 colorIndex); //改變圖層 static Acad::ErrorStatus ChangeLayer(AcDbObjectId entId,CString strLayerName); //改變線型 static Acad::ErrorStatus ChangeLinetype(AcDbObjectId entId,CString strLinetype); };
**********CModifyEnt.cpp******************* #include "StdAfx.h" #include "ModifyEnt.h" CModifyEnt::CModifyEnt(void) { } CModifyEnt::~CModifyEnt(void) { } Acad::ErrorStatus CModifyEnt::ChangeColor(AcDbObjectId entId, Adesk::UInt16 colorIndex) { AcDbEntity *pEntity = NULL; // 打開圖形數據庫中的對象 acdbOpenObject(pEntity, entId, AcDb::kForWrite); // 修改實體的顏 pEntity->setColorIndex(colorIndex);// colorIndex:0~256 的值,其中 0 表明隨塊,256 表明隨層 // 用完以後,及時關閉 pEntity->close(); return Acad::eOk; } Acad::ErrorStatus CModifyEnt::ChangeLayer(AcDbObjectId entId, CString strLayerName) { AcDbEntity *pEntity = NULL; // 打開圖形數據庫中的對象 acdbOpenObject(pEntity, entId, AcDb::kForWrite); // 修改實體的圖層 pEntity->setLayer(strLayerName); // 用完以後,及時關閉 pEntity->close(); return Acad::eOk; } Acad::ErrorStatus CModifyEnt::ChangeLinetype(AcDbObjectId entId, CString strLinetype) { AcDbEntity *pEntity = NULL; // 打開圖形數據庫中的對象 acdbOpenObject(pEntity, entId, AcDb::kForWrite); // 修改實體的線型 pEntity->setLayer(strLinetype); // 用完以後,及時關閉 pEntity->close(); return Acad::eOk; }
接下來,咱們看最重要的一部分,建立直線,建立圓(4種方法),建立圓弧(5種方法):佈局
**********CreateEnt.h******************* #pragma once #include "StdAfx.h" class CCreateEnt { public: CCreateEnt(void); ~CCreateEnt(void); // 將實體添加到圖形數據庫的模型空間 static AcDbObjectId PostToModelSpace(AcDbEntity* pEnt); // 建立一條線 static AcDbObjectId CreateLine(AcGePoint3d ptStart,AcGePoint3d ptEnd); //建立一個圓(圓心、半徑法)(三維) // ptCenter:圓心; //radius:半徑; //vec:圓所在平面 static AcDbObjectId CreateCircle(AcGePoint3d ptCenter, AcGeVector3d vec, double radius); //建立位於 XOY 平面上的圓(二維)依賴三維法 static AcDbObjectId CreateCircle(AcGePoint3d ptCenter, double radius); //建立一個圓(倆點法)依賴二維法 static AcDbObjectId CreateCircle(AcGePoint2d pt1, AcGePoint2d pt2); //建立一個圓(三點法)依賴二維法 static AcDbObjectId CreateCircle(AcGePoint2d pt1, AcGePoint2d pt2,AcGePoint2d pt3); //建立圓弧(圓心、半徑、圓弧所在的平面、起點角度和終點角度) //ptCenter:圓心; //vec:圓弧所在平面 //radius:半徑; //startAngle:起點角度 //endAngle:終點角度 static AcDbObjectId CreateArc(AcGePoint3d ptCenter, AcGeVector3d vec, double radius, double startAngle, double endAngle); //建立圓弧(二維)依賴於圓弧1法 static AcDbObjectId CreateArc(AcGePoint2d ptCenter, double radius, double startAngle, double endAngle); //建立圓弧(三點法)依賴於二維法 static AcDbObjectId CreateArc(AcGePoint2d ptStart, AcGePoint2d ptOnArc, AcGePoint2d ptEnd); //建立圓弧(起點、圓心、終點)依賴於二維法 static AcDbObjectId CreateArcSCE(AcGePoint2d ptStart, AcGePoint2d ptCenter, AcGePoint2d ptEnd); //建立圓弧(起點、圓心、圓弧角度)依賴於二維法 static AcDbObjectId CreateArc(AcGePoint2d ptStart, AcGePoint2d ptCenter, double angle); };
**********Calculation.cpp******************* #include "StdAfx.h" #include "CreateEnt.h" #include "Calculation.h" #include <math.h> #include "gearc3d.h" CCreateEnt::CCreateEnt(void) { } CCreateEnt::~CCreateEnt(void) { } AcDbObjectId CCreateEnt::CreateLine(AcGePoint3d ptStart,AcGePoint3d ptEnd) { // 在內存上建立一個新的AcDbLine對象 //AcGePoint3d ptStart(0, 0, 0); //AcGePoint3d ptEnd(100, 100, 0); AcDbLine *pLine = new AcDbLine(ptStart, ptEnd); AcDbObjectId lineId; lineId = CCreateEnt::PostToModelSpace(pLine); return lineId; } AcDbObjectId CCreateEnt::PostToModelSpace(AcDbEntity* pEnt) { // 得到指向塊表的指針 AcDbBlockTable *pBlockTable = NULL; //workingDatabase()可以得到一個指向當前活動的圖形數據庫的指針, acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead); // 得到指向特定的塊表記錄(模型空間)的指針 AcDbBlockTableRecord *pBlockTableRecord NULL; pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForWrite); // 將AcDbLine類的對象添加到塊表記錄中 AcDbObjectId entId; pBlockTableRecord->appendAcDbEntity(entId, pEnt); // 關閉圖形數據庫的各類對象 pBlockTable->close(); pBlockTableRecord->close(); pEnt->close(); return entId; } AcDbObjectId CCreateEnt::CreateCircle(AcGePoint3d ptCenter, AcGeVector3d vec, double radius) { AcDbCircle *pCircle = new AcDbCircle(ptCenter, vec, radius); // 將實體添加到圖形數據庫 AcDbObjectId circleId; circleId = CCreateEnt::PostToModelSpace(pCircle); return circleId; } AcDbObjectId CCreateEnt::CreateCircle(AcGePoint3d ptCenter, double radius) { AcGeVector3d vec(0, 0, 1); return CCreateEnt::CreateCircle(ptCenter, vec, radius); } AcDbObjectId CCreateEnt::CreateCircle(AcGePoint2d pt1, AcGePoint2d pt2) { // 計算圓心和半徑 AcGePoint2d pt = CCalculation::MiddlePoint(pt1, pt2); AcGePoint3d ptCenter(pt[X], pt[Y], 0); // 圓心 double radius = pt1.distanceTo(pt2) / 2;//distanceTo 函數用於計算兩點之間的距離,也就是半徑 // 建立圓 return CCreateEnt::CreateCircle(ptCenter, radius); } AcDbObjectId CCreateEnt::CreateCircle(AcGePoint2d pt1, AcGePoint2d pt2,AcGePoint2d pt3) { /* // 使用數學方法 double xysm, xyse, xy; AcGePoint3d ptCenter; double radius; xy = pow(pt1[X], 2) + pow(pt1[Y], 2); xyse = xy - pow(pt3[X], 2) - pow(pt3[Y], 2); xysm = xy - pow(pt2[X], 2) - pow(pt2[Y], 2); xy = (pt1[X] - pt2[X]) * (pt1[Y] - pt3[Y]) - (pt1[X] - pt3[X]) * (pt1[Y] - pt2[Y]); // 判斷參數有效性 if (fabs(xy) < 0.000001) { AfxMessageBox(_T("所輸入的參數沒法建立圓形!")); return 0; } // 得到圓心和半徑 ptCenter[X] = (xysm * (pt1[Y] - pt3[Y]) - xyse * (pt1[Y] - pt2[Y])) / (2 * xy); ptCenter[Y] = (xyse * (pt1[X] - pt2[X]) - xysm * (pt1[X] - pt3[X])) / (2 * xy); ptCenter[Z] = 0; radius = sqrt((pt1[X] - ptCenter[X]) * (pt1[X] - ptCenter[X]) + (pt1[Y] - ptCenter[Y]) * (pt1[Y] - ptCenter[Y])); if (radius < 0.000001) { AfxMessageBox(_T("半徑太小!")); return 0; } return CCreateEnt::CreateCircle(ptCenter, radius); */ // 使用幾何類 AcGeCircArc2d geArc(pt1, pt2, pt3); AcGePoint3d ptCenter(geArc.center().x, geArc.center().y, 0); return CCreateEnt::CreateCircle(ptCenter, geArc.radius()); } AcDbObjectId CCreateEnt::CreateArc(AcGePoint3d ptCenter, AcGeVector3d vec, double radius, double startAngle, double endAngle) { AcDbObjectId arcId; AcDbArc *pArc = new AcDbArc(ptCenter, vec, radius, startAngle, endAngle); arcId = CCreateEnt::PostToModelSpace(pArc); return arcId; } AcDbObjectId CCreateEnt::CreateArc(AcGePoint2d ptCenter, double radius, double startAngle, double endAngle) { AcGeVector3d vec(0, 0, 1); return CCreateEnt::CreateArc(CCalculation::Pt2dTo3d(ptCenter),vec, radius, startAngle, endAngle); } AcDbObjectId CCreateEnt::CreateArc(AcGePoint2d ptStart, AcGePoint2d ptOnArc, AcGePoint2d ptEnd) { // 使用幾何類得到圓心、半徑 AcGeCircArc2d geArc(ptStart, ptOnArc, ptEnd); AcGePoint2d ptCenter = geArc.center(); double radius = geArc.radius(); // 計算起始和終止角度 AcGeVector2d vecStart(ptStart.x - ptCenter.x, ptStart.y - ptCenter.y); AcGeVector2d vecEnd(ptEnd.x - ptCenter.x, ptEnd.y - ptCenter.y); double startAngle = vecStart.angle(); double endAngle = vecEnd.angle(); return CCreateEnt::CreateArc(ptCenter, radius, startAngle, endAngle); } AcDbObjectId CCreateEnt::CreateArcSCE(AcGePoint2d ptStart, AcGePoint2d ptCenter, AcGePoint2d ptEnd) { // 計算半徑 double radius = ptCenter.distanceTo(ptStart); // 計算起、終點角度 AcGeVector2d vecStart(ptStart.x - ptCenter.x, ptStart.y - ptCenter.y); AcGeVector2d vecEnd(ptEnd.x - ptCenter.x, ptEnd.y - ptCenter.y); double startAngle = vecStart.angle(); double endAngle = vecEnd.angle(); // 建立圓弧 return CCreateEnt::CreateArc(ptCenter, radius, startAngle, endAngle); } AcDbObjectId CCreateEnt::CreateArc(AcGePoint2d ptStart, AcGePoint2d ptCenter, double angle) { // 計算半徑 double radius = ptCenter.distanceTo(ptStart); // 計算起、終點角度 AcGeVector2d vecStart(ptStart.x - ptCenter.x, ptStart.y - ptCenter.y); double startAngle = vecStart.angle(); double endAngle = startAngle + angle; // 建立圓弧 return CCreateEnt::CreateArc(ptCenter, radius, startAngle, endAngle); }
最後,建立AutoCAD命令,達到在AutoCAD命令行中輸入命令,佈局窗口看到咱們的大斧頭的目的:命令行
**********acrxEntryPoint.cpp******************* static void HHLCreateEntsLine(void) { AcGePoint3d ptStart(0, 100, 0); AcGePoint3d ptEnd(0, -100, 0); AcDbObjectId lineId; lineId = CCreateEnt::CreateLine(ptStart, ptEnd); CModifyEnt::ChangeColor(lineId, 1); ptStart.set(-10, 100, 0); ptEnd.set(-10, -100, 0); lineId = CCreateEnt::CreateLine(ptStart, ptEnd); CModifyEnt::ChangeColor(lineId, 1); CModifyEnt::ChangeLayer(lineId, _T("虛線")); CModifyEnt::ChangeLinetype(lineId, _T("中心線")); } static void HHLCreateEntsCircle(void) { // 「圓心、半徑」法建立一個圓 AcGePoint3d ptCenter(50, 50, 0); CCreateEnt::CreateCircle(ptCenter, 5); // 兩點法建立一個圓 AcGePoint2d pt1(70, 100); AcGePoint2d pt2(130, 100); //CCreateEnt::CreateCircle(pt1, pt2); // 三點法建立一個圓 pt1.set(60, 100); pt2.set(140, 100); AcGePoint2d pt3(100, 60); //CCreateEnt::CreateCircle(pt1, pt2, pt3); } static void HHLCreateEntsArc(void) { // 建立位於XOY平面上的圓弧 AcGePoint2d ptCenter(50, -50); CCreateEnt::CreateArc(ptCenter, 100 * sqrt( (double)2 ) / 2, 1 * CCalculation::PI() / 4, 3 * CCalculation::PI() / 4); // 三點法建立圓弧 AcGePoint2d ptStart(100, 0); AcGePoint2d ptOnArc(120, 50); AcGePoint2d ptEnd(100, 100); CCreateEnt::CreateArc(ptStart, ptOnArc, ptEnd); // 「起點、圓心、終點」建立圓弧 ptStart.set(100, 100); ptCenter.set(50, 150); ptEnd.set(0, 100); CCreateEnt::CreateArcSCE(ptEnd , ptCenter, ptStart); // 「起點、圓心、圓弧角度」建立圓弧 ptStart.set(0, 0); ptCenter.set(-50, 50); CCreateEnt::CreateArc(ptStart, ptCenter, CCalculation::PI() / 2); } ACED_ARXCOMMAND_ENTRY_AUTO(CCreateEntsApp, HHL, CreateEntsLine, CreateLine, ACRX_CMD_TRANSPARENT, NULL) ACED_ARXCOMMAND_ENTRY_AUTO(CCreateEntsApp, HHL, CreateEntsCircle, CreateCircle, ACRX_CMD_TRANSPARENT, NULL) ACED_ARXCOMMAND_ENTRY_AUTO(CCreateEntsApp, HHL, CreateEntsArc, CreateArc, ACRX_CMD_TRANSPARENT, NULL)
注意:最後這部分代碼是加在現有cpp裏的,該cpp爲程序的主入口3d