1. 点在 FACE 上
如果点在FACE上,可以采用surface的直接接口:surface::param、surface::test_point和surface::test_point_tol。
virtual SPApar_pos surface::param ( const SPAposition & pos,
const SPApar_pos & param_guess = SpaAcis::NullObj::get_par_pos()
)
logical surface::test_point ( const SPAposition & pos,
const SPApar_pos & param_guess = SpaAcis::NullObj::get_par_pos(),
SPApar_pos & param_actual = SpaAcis::NullObj::get_par_pos()
)
virtual logical surface::test_point_tol ( const SPAposition & pos,
double tol = 0,
const SPApar_pos & param_guess = SpaAcis::NullObj::get_par_pos(),
SPApar_pos & param_actual = SpaAcis::NullObj::get_par_pos()
)
我更喜欢test_point_tol这个接口,因为这个接口可以设定一个阈值,而且可以判断点是否在FACE上面。
2. 点在 FACE 外
如果点point不在FACE上面,需要找到FACE上距离point最近的点closest_pos,或者将point投影到FACE上之后(得到的也是closest_pos),再去找对应的u、v参数
其中,将point投影到FACE上的接口为point_perp,如下所示:
void point_perp(
const SPAposition& pos,
SPAposition& foot,
const SPApar_pos& param_guess = SpaAcis::NullObj::get_par_pos(),
SPApar_pos& param_actual = SpaAcis::NullObj::get_par_pos(),
logical f_weak = FALSE
)
求FACE上距离point最近的点的接口为api_entity_point_distance,如下所示:
outcome api_entity_point_distance(ENTITY *ent,
SPAposition &in_point,
SPAposition &closest_pos,
double &distance,
param_info &ent_info = SpaAcis::NullObj::get_param_info(),AcisOptions *ao = NULL);
上面两个接口都提供了直接获得closest_pos的UV参数的变量,但是我实测获得的UV都是0,好像不行,获得closest_pos之后,要想得到UV,还得采用(1)中的接口来获取准确的 UV 参数。
为了方便大家测试学习,我写了一段测试代码,可直接取用。
void main()
{api_start_modeller(0);//add unlock license key here; refer to the "Application Licensing" articleunlock_spatial_products();my_initialization();// Create a cuboid.BODY* block = NULL;api_make_cuboid(30, 30, 30, block, NULL);ENTITY_LIST face_list;api_get_faces(block, face_list);std::cout << "face size = " << face_list.iteration_count() << std::endl;//2. 输出面数据int faceCount = face_list.iteration_count();for (int i = 0; i < faceCount; ++i){std::cout << "第" << i << "个面:";FACE* face = (FACE*)face_list[i];SPAposition faceCenter = compute_face_midpoint(face);SPAvector faceNormal = compute_face_midpoint_outnormal(face);std::cout << "面中点坐标 = (" << faceCenter.x() << "," << faceCenter.y() << "," << faceCenter.z() << ")" << std::endl;std::cout << "面中点外法线 = (" << faceNormal.x() << "," << faceNormal.y() << "," << faceNormal.z() << ")" << std::endl;}//3. 确定测试点和面FACE* pTestFace = (FACE*)face_list[0];surface const& pTestSurf = pTestFace->geometry()->equation();SPAposition pos1 = SPAposition(3, 12, 15);//在面上的一点SPAposition pos2 = SPAposition(0, 0, 25);//在面外的一点//4.1 测试param接口SPApar_pos param1_1 = pTestSurf.param(pos1, SPApar_pos(0.2,0.2));SPApar_pos param1_2 = pTestSurf.param(pos2, SPApar_pos(0.2, 0.2));std::cout << "测试param接口:param1_1 = " << param1_1.u << ", " << param1_1.v << ". param1_2 = " << param1_2.u << ", " << param1_2.v << std::endl;//4.2 测试point_perpSPAposition foot2_1;SPAposition foot2_2;SPApar_pos param2_1;SPApar_pos param2_2;pTestSurf.point_perp(pos1, foot2_1, SPApar_pos(0.2, 0.2), param2_1);pTestSurf.point_perp(pos2, foot2_2, SPApar_pos(0.2, 0.2), param2_2);std::cout << "测试point_perp接口:param2_1 = " << param2_1.u << ", " << param2_1.v << ". param2_2 = " << param2_2.u << ", " << param2_2.v << std::endl;std::cout << "foot2_1 = (" << foot2_1.x() << "," << foot2_1.y() << "," << foot2_1.z() << ")" << std::endl;std::cout << "foot2_2 = (" << foot2_2.x() << "," << foot2_2.y() << "," << foot2_2.z() << ")" << std::endl;//4.3 测试test_pointSPAposition foot3_1;SPAposition foot3_2;SPApar_pos param3_1;SPApar_pos param3_2;bool result1 = pTestSurf.test_point(pos1, SPApar_pos(0.2, 0.2), param3_1);bool result2 = pTestSurf.test_point(pos2, SPApar_pos(0.2, 0.2), param3_2);std::cout << "result1 = " << result1 << ",result2=" << result2 << "测试point_perp接口:param3_1 = " << param3_1.u << ", " << param3_1.v<< ". param3_2 = " << param3_2.u << ", " << param3_2.v << std::endl;//4.4 测试最短距离SPAposition closest_pos1;double distance1;param_info ent_info1;outcome result = api_entity_point_distance(pTestFace, pos1, closest_pos1, distance1, ent_info1);std::cout << "closest_pos1 = (" << closest_pos1.x() << ", " << closest_pos1.y() << ", " << closest_pos1.z() << ")" << std::endl;std::cout << "distance1 = " << distance1 << std::endl;std::cout << "uv_params = (" << ent_info1.uv().u << "," << ent_info1.uv().v << ")" << std::endl;SPAposition closest_pos2;double distance2;param_info ent_info2;result = api_entity_point_distance(pTestFace, pos2, closest_pos2, distance2, ent_info2);std::cout << "closest_pos2 = (" << closest_pos2.x() << ", " << closest_pos2.y() << ", " << closest_pos2.z() << ")" << std::endl;std::cout << "distance2 = " << distance2 << std::endl;std::cout << "uv_params = (" << ent_info2.uv().u << "," << ent_info2.uv().v << ")" << std::endl;my_termination();api_stop_modeller();
}