分享

Arx开发AcDbLine转换为AcDbPolyline的方法研究

 wtkc 2016-08-20
           [摘要:比来项目中碰到一个题目。题目描绘以下:给定一条 AcDbLine, 须要将其调换为 AcDbPolyline 。正在网上搜刮了一下,出有获得中意的谜底。无法只好本身艰难索求一番,题目根基弄定,不由赞]

最近项目中遇到一个问题。问题描述如下:给定一条AcDbLine,需要将其替换为AcDbPolyline。在网上搜索了一下,没有得到满意的答案。无奈只好自己艰苦探索一番,问题基本搞定,不禁赞叹CAD数据库的结构和Arx类库的精美与强大。现把自己的心得体会和一些疑问贴出来,望与高手交流和讨教。

AcDbLine 中端点的坐标是以AcGePoint3d保存的,而AcDbPolyline 成员函数addVertexAt函数传入的点是AcGePoint2d,一个是三维点,一个是二维点,如何转化呢?其实这涉及到CAD数据库WCS(世界坐标系)ECS(实体坐标系)如何转化的问题。WCS在此就不必多说,下面首先根据我查阅的资料谈谈ECS,在CAD数据库中有些实体的点的坐标是以该实体的自定义坐标系保存的,AcDbPolyline就是其中之一,在三维空间中,实体描述自定义的坐标系需要OCSz轴三维向量(AcGeVector3d对象),和标高(elevation)值。如果给定一个AcGeVector3d,就可以通过平移三维空间WCS的原点和围绕z轴旋转XY轴定义无穷多的坐标系。但对于相同的Z轴方向,只有一个OCS,它具有如下特性:它的原点与WCS原点一致:XY平面中的XY轴方向可以任意方式确定且一旦确定便固定不变。AutoCAD使用任意轴算法来确定此坐标系的XY轴方向向量。举个例子:假设空间直线为a,我们知道,包含a 的平面有无数个,这些平面可以组成一个平面束,任取其中一个平面,可得到其法向量n,以n为新坐标系的Z轴,n是与直线的方向向量正交的,因此直线a是平行与新定义的坐标系的xy平面的,这样,直线a两个端点在新坐标系中的z轴分量就相同了,于是就可以把z轴分量分离出来用以标高表示。将WCS空间中的三维点转换到自定坐标系中就变成了二维点和一个标高了。这就是定义实体自定义坐标系的方法。上面的论述中还有一个问题,就是OCSx轴和y轴如何确定呢?这就要用到CAD的任意轴算法了:设给定的向量为N,WCSY轴为Wy,表示成点坐标的方式为(0,1,0),Z轴为Wz,表示成点坐标的方式为(0,0,1);OCS X轴为Ax,Y轴为AyN也可作Az

则该算法可写做为:

If( abs(Nx) < 1/64) and ( abs(Ny) < 1/64 then

       Ax = Wy x N

Else

       Ax = Wz x N

上式首先检查向量Nx轴分量和y轴分量的绝对值是否小于1/64,也就是说如果NWz很接近的话就计算WyN的叉积,否则就计算WzN的叉积,这样就得到了新的x轴,将x轴单位化后,使用公式Ay = N x Wz,将Ay单位化后便得到新的y轴了。这样新的坐标系就计算出来了。

有了上面的知识后,再回到本文开头的问题。解决该问题的第一步就是要给AcDbPolyline建立一个坐标系,并得到WCSOCS的变换矩阵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!              

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多