检测射线与三角形相交(3D)

Theory:

这里有张图…

Implement:

static bool intersectSegmentTriangle(const float* sp, const float* sq,
                                     const float* a, const float* b, const float* c,
                                     float &t)
{
    float v, w;
    float ab[3], ac[3], qp[3], ap[3], norm[3], e[3];
    rcVsub(ab, b, a);
    rcVsub(ac, c, a);
    rcVsub(qp, sp, sq);
    
    // 向量叉积, @norm 为三角形法向量
    rcVcross(norm, ab, ac);
    
    // 点积, d= 0 表示垂直, 那么源线段与三角形平面平行; 
    // d<0 表示方向相反
    float d = rcVdot(qp, norm);
    if (d <= 0.0f) return false;
    
    // @t 为ap与三角形平面abc法向量的余弦值,  若t<0, 表示 p在abc平面背面
    // 若 t > d 表示ap与@norm的夹角 小于 pq与@norm的夹角, 那么pq必定不会相交于三角形内
    rcVsub(ap, sp, a);
    t = rcVdot(ap, norm);
    if (t < 0.0f) return false;
    if (t > d) return false;
    
    // 角度的可能范围
    rcVcross(e, qp, ap);
    v = rcVdot(ac, e);
    if (v < 0.0f || v > d) return false;        //同上

    w = -rcVdot(ab, e);                            //取反,因为ab向量在apq平面后面
    if (w < 0.0f || v + w > d) return false;    // v+w > d 表示  ab与apq平面的角度加上ac与apq的角度 < pq与abc平面的角度
    
    // d是单元长度, 三角形切割线段为ap和aq两部分,  t/d表示三角形正向线段占pq的百分比
    t /= d;
    
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值