打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Arx开发AcDbLine转换为AcDbPolyline的方法研究
[摘要:比来项目中碰到一个题目。题目描绘以下:给定一条 AcDbLine, 须要将其调换为 AcDbPolyline 。正在网上搜刮了一下,出有获得中意的谜底。无法只好本身艰难索求一番,题目根基弄定,不由赞]
最近项目中遇到一个问题。问题描述如下:给定一条AcDbLine,需要将其替换为AcDbPolyline。在网上搜索了一下,没有得到满意的答案。无奈只好自己艰苦探索一番,问题基本搞定,不禁赞叹CAD数据库的结构和Arx类库的精美与强大。现把自己的心得体会和一些疑问贴出来,望与高手交流和讨教。
AcDbLine 中端点的坐标是以AcGePoint3d保存的,而AcDbPolyline 成员函数addVertexAt函数传入的点是AcGePoint2d,一个是三维点,一个是二维点,如何转化呢?其实这涉及到CAD数据库WCS(世界坐标系)和ECS(实体坐标系)如何转化的问题。WCS在此就不必多说,下面首先根据我查阅的资料谈谈ECS,在CAD数据库中有些实体的点的坐标是以该实体的自定义坐标系保存的,AcDbPolyline就是其中之一,在三维空间中,实体描述自定义的坐标系需要OCS的z轴三维向量(AcGeVector3d对象),和标高(elevation)值。如果给定一个AcGeVector3d,就可以通过平移三维空间WCS的原点和围绕z轴旋转X和Y轴定义无穷多的坐标系。但对于相同的Z轴方向,只有一个OCS,它具有如下特性:它的原点与WCS原点一致:XY平面中的X和Y轴方向可以任意方式确定且一旦确定便固定不变。AutoCAD使用任意轴算法来确定此坐标系的X,Y轴方向向量。举个例子:假设空间直线为a,我们知道,包含a 的平面有无数个,这些平面可以组成一个平面束,任取其中一个平面,可得到其法向量n,以n为新坐标系的Z轴,n是与直线的方向向量正交的,因此直线a是平行与新定义的坐标系的xy平面的,这样,直线a两个端点在新坐标系中的z轴分量就相同了,于是就可以把z轴分量分离出来用以标高表示。将WCS空间中的三维点转换到自定坐标系中就变成了二维点和一个标高了。这就是定义实体自定义坐标系的方法。上面的论述中还有一个问题,就是OCS中x轴和y轴如何确定呢?这就要用到CAD的任意轴算法了:设给定的向量为N,WCS中Y轴为Wy,表示成点坐标的方式为(0,1,0),Z轴为Wz,表示成点坐标的方式为(0,0,1);设OCS X轴为Ax,Y轴为Ay,N也可作Az。
则该算法可写做为:
If( abs(Nx) < 1/64) and ( abs(Ny) < 1/64 then
Ax = Wy x N
Else
Ax = Wz x N
上式首先检查向量N的x轴分量和y轴分量的绝对值是否小于1/64,也就是说如果N与Wz很接近的话就计算Wy与N的叉积,否则就计算Wz与N的叉积,这样就得到了新的x轴,将x轴单位化后,使用公式Ay = N x Wz,将Ay单位化后便得到新的y轴了。这样新的坐标系就计算出来了。
有了上面的知识后,再回到本文开头的问题。解决该问题的第一步就是要给AcDbPolyline建立一个坐标系,并得到WCS到OCS的变换矩阵A,给定直线端点的坐标经过变换矩阵A变换后得到的两个点的坐标z轴分量应该是相同的,将其z轴分量设置为AcDbPolyline的标高,将新坐标系OCS中的Z轴向量设置为AcDbPolyline的法向量,将变换后的两点舍去其z轴分量便得到两个二维点,然后将这两个二维点添加到AcDbPolyline中,这样,AcDbLine转化为AcDbPolyline的工作便完成。
因此,关键是要得到变换矩阵A,如何实现呢?下面我谈谈自己做的一个方法,该方法比较繁琐,而且有些问题没有搞清楚,在此希望能得到高手的求证,小弟在此不胜感激。
首先,可以得到AcDbLine的法向量和方向向量,这两个向量理论上因该是正交的,代码如下:AcGeVector3d normLine = pline->normal();
AcGeVector3d vectorDircetionLine = endPoint3d - startPoint3d;
double dRes = normLine.dotProduct(vectorDircetionLine);
也就是说变量dRes的值为0,但是实际上不是的,为什么呢?目前搞不明白!
所以在此我不得不手动计算AcDbLine的一个法向量,下面贴出这个过程的代码片段:
AcGePoint3d startPoint3d = pline->startPoint();         AcGePoint3d endPoint3d = pline->endPoint();         AcGeVector3d vectorDircetionLine = endPoint3d - startPoint3d;           AcGeVector3d vectorPolyline = vectorDircetionLine;           vectorPolyline.y = 0;            double dRes = normLine.dotProduct(vectorDircetionLine);                  AcDbPolyline *pPolyline = new AcDbPolyline();                  AcGeVector3d normPolyline = vectorDircetionLine.crossProduct(vectorPolyline);                  pPolyline->setNormal(normPolyline);                  AcGeMatrix3d tranformMatrix;                  pPolyline->getEcs(tranformMatrix);                  AcGeMatrix3d inversTranformMM = tranformMatrix.inverse();                  endPoint3d.transformBy(inversTranformMM);                  startPoint3d.transformBy(inversTranformMM);                  AcGePoint2d startPoint2d(startPoint3d.x,startPoint3d.y);       AcGePoint2d endPoint2d(endPoint3d.x,endPoint3d.y); pPolyline->addVertexAt(0,startPoint2d);
pPolyline->addVertexAt(1,endPoint2d);
pPolyline->setElevation(endPoint3d.z);
相关推荐
感谢关注 Ithao123精品文库频道,ithao123.cn是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Python生成简单3D管道
unity3d 点到向量的距离算法和判断点位于向量哪一侧的算法
(学习笔记)摄像机模型与标定——三个坐标系及其之间关系
AcDbLine类
WPF 颜色渐变
抛物线算法(已知起点、终点、高度)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服