射线与三角面元求交点


#include <CSTDIO>
#include <cmath>

#define EPSILON 0.000001
/*#define CROSS(dest, v1, v2) \
    dest[0] = v1[1]*v2[2] - v1[2]*v2[1];\
    dest[1] = v1[2]*v2[0] - v1[0]*v2[2];\
    dest[2] = v1[0]*v2[1] - v1[1]*v2[0];
#define DOT(v1, v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
#define SUB(dest, v1, v2)\
    dest[0]=v1[0]-v2[0];\
    dest[1]=v1[1]-v2[1];\
    dest[2]=v1[2]-v2[2];
*/
inline void CROSS(double dest[3], double v1[3], double v2[3])
{
    dest[0] = v1[1]*v2[2] - v1[2]*v2[1];
    dest[1] = v1[2]*v2[0] - v1[0]*v2[2];
    dest[2] = v1[0]*v2[1] - v1[1]*v2[0];
}

inline double DOT(double v1[3], double v2[3])
{
    return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
}

inline void SUB(double dest[3], double v1[3], double v2[3])
{
    dest[0] = v1[0] - v2[0];
    dest[1] = v1[1] - v2[1];
    dest[2] = v1[2] - v2[2];
}

int intersect_triangle(double orig[3], double dir[3],
        double vert0[3], double vert1[3], double vert2[3],
        double *t, double *u, double *v)
{
    double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
    double det, inv_det;

    //find vectors for two edges sharing vert0
    SUB(edge1, vert1, vert0);
    SUB(edge2, vert2, vert0);

    // begin calculating determinant - also used to calculate U parameter
    CROSS(pvec, dir, edge2);

    // if determinant is near zero, ray lies in plane of triangle
    det = DOT(edge1, pvec);

#ifdef TEST_CULL // define TEST_CULL if culling is desired
    if(det < EPSILON)
        return 0;

    // calculate distance from vert0 to ray origin
    SUB(tvec, orig, vert0);

    // calculate U parameter and test bounds
    *u = DOT(tvec, pvec);
    if (*u < 0.0 || *u > det)
        return 0;

    // prepare to test V parameter
    CROSS(qvec, tvec, edge1);

    // calculate V parameter and test bounds
    *v = DOT(dir, qvec);
    if (*v < 0.0 || *u +*v > det)
        return 0;

    // calculate t, scale parameters, ray intersects triangle
    *t = DOT(edge2, qvec);
    int_det = 1.0 / det;
    *t *= inv_det;
    *u *= inv_det;
    *v *= inv_det;
#else           // the non-culling branch
    if (det > -EPSILON && det < EPSILON)
        return 0;
    inv_det = 1.0 / det;

    // calculate distance from vert0 to ray origin
    SUB(tvec, orig, vert0);

    // calculate U parameter and test bounds
    *u = DOT(tvec, pvec) * inv_det;
    if (*u < 0.0 || *u > 1.0)
        return 0;

    // prepare to test V parameters
    CROSS(qvec, tvec, edge1);

    // calculate V paremeter and test bounds
    *v = DOT(dir, qvec) * inv_det;
    if (*v < 0.0 || *u + *v > 1.0)
        return 0;

    //calculate t, ray intersects triangle
    *t = DOT(edge2, qvec) * inv_det;
#endif
    return 1;

}

int main(int argc, char* argv[])
{
    double ori[] = {0.0, 0.0, 0.0};
    double dir[] = {1.0/sqrtf(3), 1.0/sqrtf(3), 1.0/sqrtf(3)};///sqrtf(3)
    double vert0[] = {0.0, 0.0, 1.0};
    double vert1[] = {1.0, 0.0, 0.0};
    double vert2[] = {0.0, 1.0, 0.0};
    double t=0, u, v;

    for (int i=0; i<1; ++i)
    {
        intersect_triangle(ori, dir, vert0, vert1, vert2, &t, &u, &v);
        printf("%lf %lf %lf \n", t, u, v);
    }

    return 0;
}



附文献一篇 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值