zltangent 发表于 2011-8-31 19:02:52

ARX直线打断(仅限打断一条)

本帖最后由 zltangent 于 2011-8-31 19:04 编辑

小弟刚接触ARX不到3天,要求做个打断直线的DEMO.开始感觉挺难的,主要是没思路。现在作出后,感觉一般,主要是我做的情况很简单,输入长度,画第一条线,画第二条线的时候,会打断第一条线。长度取交点想被打断线两边扩展之和。
先把主要命令代码分享,有不取之处,还望大家多批评多指教;
(注:G-DB是图形数据库)
(对话框用的数据
BOOL m_bBreak;
CString m_csLineLen;
数据交换比较简单,在此不列了。
)

命令代码全部如下:
AcDbObjectId PostToModelSpace(AcDbEntity* pEnt);      // 添加实体进G-DB
// This is command 'BREAKLINE'
void T4BreakLine()
{
/************************************************************************/
/* 打断两条线代码:非模态对话框、线绘制、求交点、打断线处理函数             */
/************************************************************************/
/************************************************************************/
// 打断线长度对话框                                                            
/************************************************************************/

CAcModuleResourceOverride resOverride;      // 防止资源冲突
if(NULL == pDlg)
{
pDlg = new CBreakLineLenDlg(acedGetAcadFrame());
pDlg->Create(IDD_LINELENGTH);
pDlg->ShowWindow(SW_SHOW);
}
else
{
// 防止用户按下Esc隐藏对话框,在此若隐藏则显示出来
pDlg->ShowWindow(SW_SHOW);
}
/************************************************************************/
// 绘制直线                                                            
/************************************************************************/
ads_point ptStart, ptEnd;            // 起点,终点
AcGePoint3d ptS, ptE;            // 两线起点、终点
AcGeVector3d vptS, vptE;            // 声明被打断线起点和终点向量
AcDbObjectId polyId;             // 实体ID
int index = 0;
while(index < 2)
{   
// 第一个点
if(RTNORM != acedGetPoint(NULL, "\n输入第一个点:", ptStart))
{
   return;
}

// 获取第一条直线的起点向量坐标   
if(0 == index)
{   
   vptS.x = ptStart;
   vptS.y = ptStart;
   vptS.z = ptStart;
}

// 第二个点
if(RTNORM == acedGetPoint(ptStart, "\n输入第二个点:", ptEnd))
{
   // 保留各线的起始和终点
   ptS.x = ptStart;
   ptS.y = ptStart;
   ptS.z = ptStart;
   ptE.x = ptEnd;
   ptE.y = ptEnd;
   ptE.z = ptEnd;

   // 获取第一条直线的终点向量坐标
   if(0 == index)
   {
    vptE.x = ptEnd;
    vptE.y = ptEnd;
    vptE.z = ptEnd;
   }

   // 绘制直线
   AcDbLine *pLine = new AcDbLine(ptS, ptE);
   polyId = PostToModelSpace(pLine);      // 添加进G-DB
}

}

/************************************************************************/
// 获取交点                                                      
/************************************************************************/
AcDbEntity *pEnt0;
acdbOpenObject(pEnt0, polyId, AcDb::kForWrite);

AcDbEntity *pEnt1;
acdbOpenObject(pEnt1, polyId, AcDb::kForWrite);

AcGePoint3dArray ptArs;             // 交点坐标
AcGeVector3d ptMid;            // 存取交点向量
pEnt1->intersectWith(pEnt0, AcDb::kOnBothOperands, ptArs);

// 获取交点向量
ptMid.x = ptArs.x;
ptMid.y = ptArs.y;
ptMid.z = ptArs.z;
/************************************************************************/
// 打断处理                                                               
/************************************************************************/
// 更新数据
pDlg->UpData();

// 获取打断线长度
ads_real lineLen = 0;             // 打断线长度
BOOL bBreak = FALSE;             // 是否打断线

lineLen = strtod(pDlg->m_csBreakLineLen, NULL);
//lineLen = _ttoi(pDlg->m_csBreakLineLen);
bBreak = pDlg->m_bBreak;

AcGeVector3d pt1, pt2;      // 声明两个打断点向量            
AcGePoint3d pt1E, pt1S;      // 声明存储打断点的保留变量
AcGeVector3d ptNormal;      // 声明被打断线的单位向量   

ptNormal = vptE - vptS;      // 获得被打断线的向量
ptNormal = ptNormal.normalize();   // 使被打断单位向量单位化

// 获取打断点         
pt1 = ptMid - ptNormal * (lineLen / 2);
pt2 = ptMid + ptNormal * (lineLen / 2);
acutPrintf("\nptMid.x y z: %f\t\t%f\t\t%f", ptMid.x, ptMid.y, ptMid.z);
acutPrintf("\npt1.x y z: %f\t\t%f\t\t%f", pt1.x, pt1.y, pt1.z);
acutPrintf("\npt2.x y z: %f\t\t%f\t\t%f\n", pt2.x, pt2.y, pt2.z);

// 转换向量打断点为普通坐标
pt1E.x = pt1.x;
pt1E.y = pt1.y;
pt1E.z = pt1.z;
pt1S.x = pt2.x;
pt1S.y = pt2.y;
pt1S.z = pt2.z;

// 打断
if(bBreak)
{
// 绘制1
((AcDbLine*)pEnt0)->setEndPoint(pt1E);
pEnt0->close();

// 绘制2
AcDbLine *pLine1 = new AcDbLine(pt1S, ptE);
PostToModelSpace(pLine1);
}
else
{
acutPrintf("未选择打断!");
}

/************************************************************************/
// last-close                                                            
/************************************************************************/
pEnt1->close();
pDlg->DestroyWindow();
}


AcDbObjectId PostToModelSpace(AcDbEntity* pEnt)
{
// 获取当前活动G-DB的块表指针
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,
AcDb::kForRead);

// 获取块表记录指针
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);

// 添加实体进G-DB
AcDbObjectId entId;
pBlockTableRecord->appendAcDbEntity(entId, pEnt);

// last-close
pBlockTable->close();
pBlockTableRecord->close();
pEnt->close();

return entId;
}


以上比较简单,用到的也比较少,我会再努力,完善,可以打断多条。请大家不要吐我啊。交流为主。

chpmould 发表于 2011-8-31 19:14:32

不错,支持一下.

zltangent 发表于 2011-8-31 22:15:47

谢谢chpmould,呵呵
页: [1]
查看完整版本: ARX直线打断(仅限打断一条)