直接上代码吧,主要是使用了UF_CSYS_map_point函数:
bool CAMToolPathToolkit::MapPointThroughRootWork(const AUTUMOONMathPoint3d &iPt, AUTUMOONMathPoint3d &oPt, int nTransMethod)
{
// 将点坐标转换为工作坐标系下坐标
double arrPointInput[3] = {0};
double arrPointOutput[3] = {0};
iPt.Array(arrPointInput);
int nRet = -1;
switch (nTransMethod)
{
case 0:
nRet = UF_CSYS_map_point(UF_CSYS_WORK_COORDS, arrPointInput, UF_CSYS_ROOT_WCS_COORDS, arrPointOutput);
break;
case 1:
nRet = UF_CSYS_map_point(UF_CSYS_ROOT_WCS_COORDS, arrPointInput, UF_CSYS_WORK_COORDS, arrPointOutput);
break;
default:
break;
}
oPt = AUTUMOONMathPoint3d(arrPointOutput[0], arrPointOutput[1], arrPointOutput[2]);
return nRet == 0;
}
但是这里有限制,即只实现了当前工作坐标系和根坐标系之间的转换,那么如果想实现任意坐标系的转换呢,当然我们可以通过根坐标系作为媒介,实现任意坐标系之间的转换,那么有没有更好的办法,实现坐标系之间的直接转换呢?
上面的代码可以理解为简单的UF_CSYS_map_point函数使用范例,而实际上我们更需要的是从任意一个坐标系转换到任意一个坐标系的功能,那么如何实现内容——实际上利用移动对象功能,因为移动对象功能中包含从一个坐标系移动到另一个坐标系的方法。
在这里我先分享一下在nx中创建坐标系的代码:
tag_t CAMToolPathToolkit::CreateCSYSByOriginZ(const AUTUMOONMathPoint3d &iPtOrigin, const AUTUMOONMathVector3d &ivecZ,
bool bSetWCS /*= true*/)
{
int ret = 0;
double wcs_mtx[9] = {0.0};
double arrVectorZ[3] = {0};
ivecZ.Array(arrVectorZ);
ret = UF_MTX3_initialize_z(arrVectorZ, wcs_mtx);
if (ret)
{
return NULL_TAG;
}
tag_t matrix_id = NULL_TAG;
tag_t csys_id = NULL_TAG;
UF_CSYS_create_matrix(wcs_mtx, &matrix_id);
double arrOrigin[3] = {0};
iPtOrigin.Array(arrOrigin);
if (matrix_id != NULL_TAG)
{
UF_CSYS_create_csys(arrOrigin, matrix_id, &csys_id);
if (csys_id != NULL_TAG)
{
// 设置新建的坐标系为当前工作坐标系
if (bSetWCS)
{
UF_CSYS_set_wcs(csys_id);
}
// 设置坐标系为显示状态
// UF_CSYS_set_wcs_display(1);
return csys_id;
}
}
return NULL_TAG;
}
tag_t CAMToolPathToolkit::CreateCSYSByOriginXZ(const AUTUMOONMathPoint3d &iPtOrigin, const AUTUMOONMathVector3d &ivecX,
const AUTUMOONMathVector3d &ivecZ, bool bSetWCS)
{
double iX[3] = {0};
double iZ[3] = {0};
ivecX.Array(iX);
ivecZ.Array(iZ);
int errorCode = 0;
double valueOfX = sqrt(pow(iX[0], 2) + pow(iX[1], 2) + pow(iX[2], 2));
double valueOfZ = sqrt(pow(iZ[0], 2) + pow(iZ[1], 2) + pow(iZ[2], 2));
if (fabs(valueOfX) < 0.001 || fabs(valueOfZ) < 0.001)
{
errorCode = 1;
return NULL_TAG;
}
UF_initialize();
double OriginPoint[3];
iPtOrigin.Array(OriginPoint);
UF_CSYS_map_point(UF_CSYS_WORK_COORDS, OriginPoint, UF_CSYS_ROOT_COORDS, OriginPoint);
double y_vec[3];
y_vec[0] = iZ[1] * iX[2] - iZ[2] * iX[1];
y_vec[1] = iZ[2] * iX[0] - iZ[0] * iX[2];
y_vec[2] = iZ[0] * iX[1] - iZ[1] * iX[0];
double mtx[9] = {0};
UF_CALL(UF_MTX3_initialize(iX, y_vec, mtx));
UF_MTX3_ortho_normalize(mtx);
tag_t matrix_id;
UF_CALL(UF_CSYS_create_matrix(mtx, &matrix_id));
tag_t oCsys_tag;
UF_CALL(UF_CSYS_create_csys(OriginPoint, matrix_id, &oCsys_tag));
// 设置新建的坐标系为当前工作坐标系
if (bSetWCS && oCsys_tag)
{
UF_CSYS_set_wcs(oCsys_tag);
}
return oCsys_tag;
}
接下来是坐标系之间的代码转换:
AUTUMOON::AUTUMOONMathPoint3d CCommonHelper::MapPointFromCSYSToCSYS(const AUTUMOONMathPoint3d &iptInput, tag_t tgFromCSYS,
tag_t tgToCSYS)
{
std::vector vPts = CreatePoints(std::vector(1, iptInput));
if (vPts.size() == 1)
{
tag_t tgPoint = CCommonHelper::MoveObjects(vPts[0], tgFromCSYS, tgToCSYS);
double dCoors[3] = {0};
UF_CURVE_ask_point_data(tgPoint, dCoors);
DeleteObjectsSafely(tgPoint);
return AUTUMOONMathPoint3d(dCoors);
}
return AUTUMOONMathPoint3d();
}
其中:MoveObjects为关键函数,此函数通过操作记录功能,也就是录制宏,即可实现。
因为项目原因,这里提供代码供参考,当然实际上如果你需要用到,必须做一些修改才可以使用,建议自己录制,对照修改即可。
tag_t CCommonHelper::MoveObjects(NXObject *ipObj, tag_t tgFromCSYS, tag_t tgToCSYS, bool bCopy /*= false*/)
{
// 获取坐标系
CartesianCoordinateSystem *cartesianCoordinateSystemFrom =
static_cast(NXObjectManager::Get(tgFromCSYS));
CartesianCoordinateSystem *cartesianCoordinateSystemTo =
static_cast(NXObjectManager::Get(tgToCSYS));
Features::MoveObject *nullFeatures_MoveObject(NULL);
Features::MoveObjectBuilder *moveObjectBuilder1;
moveObjectBuilder1 = AUTUMOONWorkPart->BaseFeatures()->CreateMoveObjectBuilder(nullFeatures_MoveObject);
Unit *unit1 = moveObjectBuilder1->TransformMotion()->RadialOriginDistance()->Units();
Point3d manipulatororigin1 = moveObjectBuilder1->TransformMotion()->ManipulatorOrigin();
Matrix3x3 manipulatormatrix1;
manipulatormatrix1 = moveObjectBuilder1->TransformMotion()->ManipulatorMatrix();
moveObjectBuilder1->TransformMotion()->SetOption(GeometricUtilities::ModlMotion::OptionsCsysToCsys);
moveObjectBuilder1->TransformMotion()->DistanceValue()->SetRightHandSide("20");
bool added1 = moveObjectBuilder1->ObjectToMoveObject()->Add(ipObj);
Unit *unit2 = moveObjectBuilder1->TransformMotion()->DistanceAngle()->Angle()->Units();
moveObjectBuilder1->TransformMotion()->SetFromCsys(cartesianCoordinateSystemFrom);
moveObjectBuilder1->TransformMotion()->SetToCsys(cartesianCoordinateSystemTo);
if (bCopy)
{
moveObjectBuilder1->SetMoveObjectResult(Features::MoveObjectBuilder::MoveObjectResultOptionsCopyOriginal);
}
NXObject *nXObject1 = moveObjectBuilder1->Commit();
std::vector objects2 = moveObjectBuilder1->GetCommittedObjects();
moveObjectBuilder1->Destroy();
// 成功移动对象
if (objects2.size())
{
return objects2[0]->Tag();
}
return NULL_TAG;
}