CAD坐标系概念
CAD中,共有5种坐标系统,其种类与定义分别如下:
1.WCS
世界坐标系即World Coordinate System
。其它所有的坐标系都是相对WCS定义的,WCS是永远不改变的。相对于WCS测量的值可以忽略其它坐标系统的变化。
2.UCS
用户坐标系统即User Coordinate System
。用户指定一个UCS以便绘图更容易。所有传到AutoCAD命令的点,包括那些从ObjectArx程序和外部功能返回的,都是当前UCS的点(除了在命令提示符后用户在前面加了个*的点)。通常,我们在自定义实体中使用的点都是以WCS来考虑的,当创建此实体时,如果需要用户输入一个点,由于此时CAD工作在UCS当中,得到的这个点需要转换成WCS,这样自定义实体才能正确地处理此点,否则将会产生错误。同理,如果自定义实体需要在UCS中显示出来时,也要需要将WCS转换成UCS。转换的函数是:acedTrans
,关于此函数的使用,大家可以参考Arx的帮助文档“Coordinate System Transformations”这一节。
3.ECS
对象坐标系统-由polyline
对象的某些方法和属性指定的点的值由这种坐标系统表达,与对象有关。这些点通常根据对象的用途被转换成WCS、当前的UCS或当前的DCS。相反的,在WCS、UCS或DCS中的点依靠相同的属性写进数据库之前,必须被转换成ECS。当从ECS转换坐标或转换坐标到ECS时,你必须输入acedTrans函数中的最后一个参数ECS法线。
4.DCS
显示坐标系统即对象在显示前被转换的坐标系统
。DCS的原点是被存在AutoCAD系统变量TARGET中的点,它的Z轴就是视图方向。换句话说,一个视口始终是它的DCS平面图。这些坐标可用于决定物体是从哪里显示给AutoCAD用户的。
5.PSDCS
图纸空间DCS-该坐标系统只能从当前活动的模型空间视口的DCS转入或转出。这本来是一个二维的转换,如果Disp变量为FALSE,X和Y坐标总是按比例来偏移的。Z坐标也是按比例的但是从不转换。因此,可以用Z坐标来找到两个坐标系统之间的比例因子。PSDCS只能被转换成当前的模型空间视口。如果转来的变量等于PSDCS,那么输出的变量必须等于DCS,反之亦然。
坐标系的转换
static void BasicTramsforms(AcDbEntity* pEnt)
{
//最近做一个ARX项目,要求在三维空间的不同视角下用鼠标拖动绘制或布置实体
//主要用到以下函数或方法:
/*
acedGetCurrentUCS(AcGeMatrixed&); //获取当前UCS转换矩阵,通过这个矩阵可以将UCS转换为WCS
AcGeMatrix::inverse(); //获取逆向转换矩阵。
AcGePoint3d::transformBy(AcGeMatrixed&); //根据矩阵,转换点坐标。
AcDbEntity::transformBy(AcGeMatrixed&); //对实体进行矩阵转换。
AcDbExtents::transformBy(AcGeMatrixed&); //对范围进行矩阵转换。
*/
//绘制时视角为当前UCS的XY轴平面。用鼠标拖动点选的坐标肯定为UCS坐标,直接用这个坐标绘制,不用进行转换,绘制好后转换一次就好。代码如下:
AcGeMatrix3d mat;
acedGetCurrentUCS(mat);
pEnt->transformBy(mat);
//如果要用鼠标拖动实体:
AcGePoint3d oldPt; //原来所在位置 如果是WCS要转换为UCS
AcGePoint3d newPt; //现在所在位置 当前鼠标所在位置,肯定是UCS
oldPt.transformBy(mat);
newPt.transformBy(mat);
AcGeMatrix3d offset_mat;
offset_mat.setToIdentity();
offset_mat(0, 3) = newPt.x - oldPt.x;
offset_mat(1, 3) = newPt.y - oldPt.y;
offset_mat(2, 3) = newPt.z - oldPt.z;
pEnt->transformBy(mat);
//如果要判断当前点在某个实体XY轴平面范围内:
AcGePoint3d insertPt; //要判断的点
AcGeMatrix3d mat2;
acedGetCurrentUCS(mat2);
AcDbExtents extents;
pEnt->getGeomExtents(extents); //pEnt为实体指针。
extents.transformBy(mat2.inverse()); //获取的范围为WCS,要转换为UCS。注意 mat.inverse()只返回值,不改变mat本身。
if (insertPt[X] >= extents.minPoint().x && insertPt[X] <= extents.maxPoint().x &&insertPt[Y] >= extents.minPoint().y && insertPt[Y] <= extents.maxPoint().y)
{
//.....
}
}