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" article
unlock_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_perp
SPAposition 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_point
SPAposition 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();
}