iCAx开思工具箱

标题: 请问有没有api可以判断一个点是否在一个面中? [打印本页]

作者: zaixiang    时间: 2005-12-21 18:41
标题: 请问有没有api可以判断一个点是否在一个面中?
如题。有的话,就不用自己去写了。
作者: pzytony    时间: 2005-12-21 20:40
不知道
作者: supergirl    时间: 2005-12-21 21:00
UF_EVALSF_ask_minimum_face_dist
得到一点到face所在的surface的最小距离。你可以判断这个距离是否小于某个值,如果小于它,就可以认为是在这个face上。同时这个函数还会返回这一点投影到这个face上的点的坐标。
作者: zaixiang    时间: 2005-12-22 14:36
谢谢。你这个想法不错。我本来还以为要写个算法来判断。
count ← 0;
    以P为端点,作从右向左的射线L;
    for 多边形的每条边s
     do if P在边s上
          then return true;
        if s不是水平的
          then if s的一个端点在L上
                 if 该端点是s两端点中纵坐标较大的端点
                   then count ← count+1
               else if s和L相交
                 then count ← count+1;
    if count mod 2 = 1
      then return true;
    else return false;
作者: supergirl    时间: 2005-12-22 14:53
这是最基本的功能,一般都不用自己写算法的。
作者: supergirl    时间: 2005-12-22 15:00
而且我看你的算法,如果face不是很规则,中间有凹凸,好像有些问题,
作者: zaixiang    时间: 2005-12-22 15:35
凸凹多没问题的。我刚才按你说的去做。可没调试出来。帮我看下吧。
                                                               UF_EVALSF_p_t *evaluator;
                        UF_EVALSF_pos3_s srf_pos3;
                        double point[3];
                        point[0] = operation.face.getPoint().getX();
                        point[1] = operation.face.getPoint().getY();
                        point[2] = operation.face.getPoint().getZ();
                        UF_EVALSF_initialize(face_id,evaluator);
                        srf_pos3.distance =0;
                        srf_pos3.pnt3[0] =0;
                        srf_pos3.pnt3[1] =0;
                        srf_pos3.pnt3[2] =0;
                        srf_pos3.uv[0] = 0;
                        srf_pos3.uv[1] = 0;
               
                        UF_EVALSF_ask_minimum_face_dist(*evaluator,point,&srf_pos3);
                                                               if (fabs(srf_pos3.distance) <= 1e-6)
                                                                {....................................}
                                                                UF_EVALSF_free(evaluator);
作者: supergirl    时间: 2005-12-22 16:45
UF_EVALSF_p_t evaluator;
UF_EVALSF_initialize(face_id,&evaluator);
UF_EVALSF_ask_minimum_face_dist(evaluator,point,&srf_pos3);
UF_EVALSF_free(&evaluator);
作者: airen    时间: 2005-12-23 11:03
很简单。。

做已知点 投影到曲面上。。。  比较已知点 和 投影点间距离。。。

若>0  那么不在面上
反之
作者: mizzle    时间: 2005-12-24 09:43
UF_MODL_ask_point_containment就可以吧
作者: 深夜摔键盘    时间: 2005-12-24 12:06
UF_EVALSF_ask_minimum_face_dist ,UGS只提供了这个接口,但无法使用,这个函数应该是个空壳,不知什么缘故!

另外,楼主的算法是判断点在多边形内的阿,和face有什么关系!3D空间的face,2D空间是没法解决的。

3D face上寻找目标点的最近点,至今为止只能通过自写程序来完成,我看了NX4的OPEN API,UF_EVALSF_ask_minimum_face_dist 依然为空的。因为UF_EVALSF_initialize的返回值为空。

程序要写,也不是很难。首先要获取face的控制点、阶数、段数,然后组织成曲面方程,然后再通过缩小u,v参数范围来确定曲面上距离目标点的最近点。缩小参数范围,可以采用二分法,当然,二分法是真对一维的,u,v参数范围的缩小要改造一下。
作者: zaixiang    时间: 2005-12-24 23:14
UF_EVALSF_ask_minimum_face_dist可以用的。已经调试成功了。我本来用那个算法也行的。本来打算获取face的tag后,在获取face的每个vertex。这样就可以把那个face看成一个多边行。当然这样的话就不能处理曲面了。
作者: 深夜摔键盘    时间: 2005-12-25 14:00
[quote]原帖由
作者: zaixiang    时间: 2005-12-25 14:35
1、需要按照下面这样做才会对。
     UF_EVALSF_p_t evaluator;//我觉得这样声明的话,系统就会自动给他初始化;假设声明为指针的话,调用下面                                            //个函数就会得到你说的那种情况。
     UF_EVALSF_initialize(face_id,&evaluator);
2、我是指face的边界点。
作者: 深夜摔键盘    时间: 2005-12-25 16:14
1.现在没在WINDOWS下,也没法验证一下。感觉 UF_EVALSF_p_t evaluator作为指针变量,未经初始化,就传递给一个API,与UG的开发规范不太吻合。如果你真的测试通过,那也很好的了,起码它能用。以前,我以为UF_EVALSF_ask_minimum_face_dist是个空壳,在uf_eval.h中,有一个查找与曲线最近点的API,是必须要使用初始化函数的。

2.射线法只能用在二维的情况,内外,只是真对于二维多边形的。如果你的多边形的各顶点并非在一个平面上,射线法就无效了,此时,空间中的点相对与这样的多边形,也就无内外的说法了。如果真要自写程序实现你需要的功能,确定曲面方程是必须的。


作者: zaixiang    时间: 2005-12-25 16:52
ug公司我去过的,太垃圾了。做的东西实在不怎么样。
作者: supergirl    时间: 2005-12-27 09:42
楼主老大,我觉得是你的C语言基本功不过关,所以那个函数才没有出来。
UF_EVALSF_p_t evaluator;已经是一个指针了。函数是要求你传入一个结构体的两重指针进去,然后在里面给你结构体指针分配空间。至于为什么要这样做,是因为那个结构体里面要返回指针,所以需要你传入两重指针。所以应该是
UF_EVALSF_p_t evaluator;
UF_EVALSF_initialize(face_id,&evaluator);
而不是
UF_EVALSF_p_t *evaluator;
UF_EVALSF_initialize(face_id,evaluator);
UG的函数大部分要分配空间的都是这样用的啊。可惜你没有好好的看函数说明。

出现错误的时候首先要怀疑自己,不要去指责别人的API。
我看见很多初学的人,函数一出错,首先就去怀疑API,结果99.99999%的情况都是自己的错误。
作者: 深夜摔键盘    时间: 2005-12-27 20:29
supergirl ,有空你也帮着测测吧。刚才我又试了一下,
UF_EVALSF_p_t evaluator;
UF_EVALSF_initialize(face_id,&evaluator);
这样子,搞不定,evaluator总是空值。而且在头文件中,怎么也找不到UF_EVALSF_s这个结构体的定义。

在做课题时,我想测点云到曲面的距离,结果,搞了好久也没搞定。末了,是自己获取的曲面方程来搞的。

我刚才做的源程序如下:
#include <stdio.h>
#include <uf.h>
#include <uf_exit.h>
#include <uf_ui.h>
#include <uf_curve.h>
#include <uf_evalsf.h>


static int init_proc1(UF_UI_selection_p_t select,void* user_data)
{
    int num_triples = 1;
    UF_UI_mask_t mask_triples[] = {
        UF_point_type,0,0};
    /* enable only lines and edges */
    if((UF_CALL(UF_UI_set_sel_mask(select,
            UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
            num_triples, mask_triples))) == 0)
    {
        return (UF_UI_SEL_SUCCESS);
    }
    else
    {
        return (UF_UI_SEL_FAILURE);
    }
}

tag_t selectPt(void)
{
        char cue[] = "选择目标点";
    char title[] = "目标点";
    int response;
    tag_t object, view;
    double cursor[3];
    if(!UF_CALL(UF_UI_select_with_single_dialog(cue,title,
                   UF_UI_SEL_SCOPE_NO_CHANGE, init_proc1, NULL,
                   &response, &object, cursor, &view)))
    {
        if (response == UF_UI_OBJECT_SELECTED ||
            response == UF_UI_OBJECT_SELECTED_BY_NAME)
        {
            if (response == UF_UI_OBJECT_SELECTED)
            {
               return object;
            }
        }
        /* unhighlight selected object */
        UF_DISP_set_highlight(object,0);
    }
        return 0;
}

static int init_proc2(UF_UI_selection_p_t select,void* user_data)
{
    int num_triples = 1;
    UF_UI_mask_t mask_triples[] = {
         UF_solid_type, UF_solid_face_subtype, UF_OBJ_sheet_body_property};
    /* enable only lines and edges */
    if((UF_CALL(UF_UI_set_sel_mask(select,
            UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
            num_triples, mask_triples))) == 0)
    {
        return (UF_UI_SEL_SUCCESS);
    }
    else
    {
        return (UF_UI_SEL_FAILURE);
    }
}

tag_t selectSurf(void)
{
        char cue[] = "选择曲面";
    char title[] = "曲面选择";
    int response;
    tag_t object, view;
    double cursor[3];
    if(!UF_CALL(UF_UI_select_with_single_dialog(cue,title,
                   UF_UI_SEL_SCOPE_NO_CHANGE, init_proc2, NULL,
                   &response, &object, cursor, &view)))
    {
        if (response == UF_UI_OBJECT_SELECTED ||
            response == UF_UI_OBJECT_SELECTED_BY_NAME)
        {
            if (response == UF_UI_OBJECT_SELECTED)
            {
               return object;
            }
        }
        /* unhighlight selected object */
        UF_DISP_set_highlight(object,0);
    }
        return 0;
}

extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
    if( UF_CALL(UF_initialize()) )
    {
        return;
    }

        double point_coords[ 3 ];
                      tag_t ptTag = selectPt();
        UF_CURVE_ask_point_data (ptTag, point_coords);

        tag_t surfTag = selectSurf();
       
        UF_EVALSF_p_t evaluator;
        UF_EVALSF_initialize (surfTag, &evaluator);

        UF_EVALSF_pos3_t  srf_pos3;
        UF_EVALSF_ask_minimum_face_dist (evaluator,point_coords,&srf_pos3 );


    UF_CALL(UF_terminate());
}


extern int ufusr_ask_unload( void )
{
    return( UF_UNLOAD_IMMEDIATELY );
}
作者: 深夜摔键盘    时间: 2005-12-27 20:44
关于UF_EVALSF_p_t,我唯一查到的信息是在uf_evalsf.h中,而这个头文件,没写入文档中,就下面这些:
typedef struct       UF_EVALSF_S                        *UF_EVALSF_p_t;
typedef const struct UF_EVALSF_S                        *UF_EVALSF_pc_t;

UF_EVALSF_S这个结构体的定义,头文件中没出现。

当时,让我郁闷了好几天。
作者: thriller    时间: 2005-12-28 15:32
用下面这个函数吧,能直接找到面上距离该点最近的点,还能得到最近点的u v参数
UF_EVALSF_find_closest_point
作者: zaixiang    时间: 2005-12-29 20:52
我更是觉得你的c语言不过关吧。哈哈
UF_EVALSF_p_t evaluator;
UF_EVALSF_initialize(face_id,&evaluator);

UF_EVALSF_p_t *evaluator;
UF_EVALSF_initialize(face_id,evaluator);
有区别吗?????其实2种方法传进去的都是2重指针。只是第一种声明方法会自动初始化evaluator,而第2中不会。而不是你说的什么2重指针的问题,看来是你没理解指针吧。


//楼主老大,我觉得是你的C语言基本功不过关,所以那个函数才没有出来。
UF_EVALSF_p_t evaluator;已经是一个指针了。函数是要求你传入一个结构体的两重指针进去,然后在里面给你结构体指针分配空间。至于为什么要这样做,是因为那个结构体里面要返回指针,所以需要你传入两重指针。所以应该是
UF_EVALSF_p_t evaluator;
UF_EVALSF_initialize(face_id,&evaluator);
而不是
UF_EVALSF_p_t *evaluator;
UF_EVALSF_initialize(face_id,evaluator);
UG的函数大部分要分配空间的都是这样用的啊。可惜你没有好好的看函数说明。

出现错误的时候首先要怀疑自己,不要去指责别人的API。
我看见很多初学的人,函数一出错,首先就去怀疑API,结果99.99999%的情况都是自己的错误。
作者: supergirl    时间: 2005-12-30 09:18
当然是有区别的,你把你的这段程序弄进去看看,你会看到NX死得有多难看。UF_EVALSF_initialize里面要为UF_EVALSF_p_t里面的数据结构分配地址。所以必须要传有地址的指针进去。UF里面大量的函数都是这样来分配地址,再传出来的。

年轻人啊,接受不了一点批评意见,也不看看自己的程序对不对。

这个帖子我不会再回了,你自己玩儿去吧
作者: 深夜摔键盘    时间: 2005-12-30 09:29
对于UG API指针型参数的问题,我的看法是这样的。

首先,对于一维指针类型的参数,如果API没有特别说明让你自行释放空间时,那么你必须为这个指针开辟空间,或者使用变量取址的方式。当API说明了让你待它执行完毕,要使用UF_free释放空间,那么,你就没必要去为这个指针参数开辟空间了,可以直接声明一个指针传给API即可。

而对于二维指针,情况有些复杂,这种复杂性,主要是涉及到怎样为二维指针开辟空间的问题。譬如对于一个二维指针int **p,为之开辟空间需要两个步骤:
1:p = new int *;
2:*p = net int;

这样,如果UG OPEN C API对于二维指针参数,如果没要求API执行结束后用户对之自行释放,那么你需要为之进行类似于上面两步的空间分配。如果API宣称用户需要使用UF_reee释放指针空间的话,那就要看API内部对二维指针参数是否只执行第2步分配,还是步骤1和步骤2都执行。如果是前者,那么surpergirl的说法是正确的,zaixiang的方法就不对了。如果是后者,那么surpergirl说的参数传递方式依然正确,zaixiang的方法也对,只是surpergirl的方法,可能要多浪费一点内存了。当然如果实在拿不准,那么surpergirl说的方式是比较可靠的。

也不知道我这样子分析,是不是对。


作者: supergirl    时间: 2005-12-30 10:22
zaixiang的方法,如果里面要开空间,他传个空地址进去,是要crash的,因为是要对地址里面指向的指针开空间,所以我说这是个二维指针的问题。如果他开了空间,传进去,里面又在开空间,是要内存泄漏的。


一维指针情况都是要求一个传一个XXX_p_t(注意,在UF中,p_t肯定都是指针了),一般你定义一个XXX_t  aaa传进去,把&aaa传进去,或者你自己为XXX_p_t开了空间,传进去。

二维的情况一般是要求传一个XXX_p_t *,一般你定义一个XXX_p_t aaa = NULL,然后把&aaa传进去,他们会为aaa在里面开空间,然后出来叫UF_free。

三维的情况是要求传一个XXX_p_t **,你定义一个一个XXX_p_t *aaa = NULL;传&aaa进去,他们会为aaa和*aaa开空间,这种出来要UF_free两次。这种一般都是传一个数组出来的或者是list之类的东东,同时它会告诉你它的number。

UF里面大量的用法都是这样的,他们喜欢这样写,你就得忍受。不过时间久了,也就习惯了。

PS:这个贴我是回键盘兄弟的,不是回楼主的。


作者: 深夜摔键盘    时间: 2005-12-30 11:18
呵呵,明白。

有争论倒不要紧,把问题讨论透彻了,就好多了。

来这里的目的,就是学东西而已。
作者: zaixiang    时间: 2005-12-30 14:39
你也是的。受不了批评。我不是说了吗?“只是第一种声明方法会自动初始化evaluator,而第2中不会。”这个自动初始化就包括给他分配个地址,以及值的初始化。




欢迎光临 iCAx开思工具箱 (https://t.icax.org/) Powered by Discuz! X3.3