ACIS中如何求点在FACE参数域内的坐标

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();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值