raytrace3.3解析

本文介绍了一个KD树实现中寻找最佳分裂点的算法过程。该算法通过遍历凸体三角面元点集,考虑TT_MIN和TT_MAX类型点作为候选分裂点,优化分割成本并确定最优分割位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bool KdTree::CalcBestSplit( double totalObjectCosts, double costToBeat,
                        const ExtentTripleArrayInfo& extents,
                        double minOnAxis, double maxOnAxis,
                        double secondAxisLen, double thirdAxisLen,
                        double* retNewBestCost, double* retSplitValue,
                        long* retNumTriplesToLeft, long* retNumObjectsToLeft, long* retNumObjectsToRight,
                        double* retCostObjectsToLeft, double* retCostObjectsToRight )
{
    if ( minOnAxis>=maxOnAxis ) {
        return false;        // We do not support splitting a zero length axis.
    }

    InitSplitCostFunction( minOnAxis, maxOnAxis, secondAxisLen, thirdAxisLen,
                            costToBeat, totalObjectCosts );

    bool foundBetter = false;
    double bestCost = costToBeat;            // Cost to beat
    long numTriplesLeft = 0;                // number of triples processed so far
    long numTriples = extents.NumTriples(); // total number of triples
    long numObjectsLeft = 0;                    // number of ojects on the left during the scan
    long numObjectsRight = extents.NumObjects();    // number of objects on the right during the scan
    double costLeft = 0.0;                    // cost of objects on the left during the scan
    double costRight = totalObjectCosts;    // total cost of objects still on the right side during scan    
    ExtentTriple* etPtr = extents.TripleArray;
    bool inFirstHalf = true;            // If still scanning first half, measured in distance along axis
    double midPoint = 0.5*(minOnAxis+maxOnAxis);
    while ( numTriplesLeft<numTriples ) {
        // The split can occur either right before or right after the split value.
        double thisSplitValue = etPtr->ExtentValue;
        bool sameSplitValue = true;
        ExtentTriple::TripleType thisType = etPtr->ExtentType;
        if ( inFirstHalf && thisSplitValue>midPoint ) {
            inFirstHalf = false;
        }

        // Skip past all TT_MAX's, and TT_FLAT's in first half, with this split value
        while ( numTriplesLeft<numTriples ) {
            if ( !(
                (( thisType==ExtentTriple::TT_MAX || (thisType==ExtentTriple::TT_FLAT && inFirstHalf) ))
                    && sameSplitValue
                    )
                )
            {
                break;
            }
            UpdateLeftRightCosts( *etPtr, &numObjectsLeft, &numObjectsRight, &costLeft, &costRight );
            etPtr++;
            numTriplesLeft++;
            thisType = etPtr->ExtentType;
            sameSplitValue = (etPtr->ExtentValue <= thisSplitValue);
        }

        // Ready to call the cost function
        // If the cost function gives better value, save everything appropriately
        if ( CalcSplitCost( thisSplitValue, costLeft, costRight, &bestCost ) ) {
            foundBetter = true;
            *retNewBestCost = bestCost;
            *retSplitValue = thisSplitValue;
            *retNumTriplesToLeft = numTriplesLeft;
            *retNumObjectsToLeft = numObjectsLeft;
            *retNumObjectsToRight = numObjectsRight;
            *retCostObjectsToLeft = costLeft;
            *retCostObjectsToRight = costRight;
        }

        // Skip past all TT_MIN's, and TT_FLAT's in second half, with this split value
        while ( numTriplesLeft<numTriples ) {
            if ( !( sameSplitValue &&  
                    (thisType==ExtentTriple::TT_MIN
                    || (thisType==ExtentTriple::TT_FLAT && !inFirstHalf)) ) )
            {
                break;
            }
            // Move rightward a triple
            UpdateLeftRightCosts( *etPtr, &numObjectsLeft, &numObjectsRight, &costLeft, &costRight );
            etPtr++;
            numTriplesLeft++;
            thisType = etPtr->ExtentType;
            sameSplitValue = (etPtr->ExtentValue <= thisSplitValue);
        }

    }

    return foundBetter;

}


凸体的三角面元的点集合 ,其一个点是某一个面元的TT_MIN ,也是另外某个三角面元的TT_MAX. 若是TT_FLAT 则就是自己不与其他面元公用:



所以以midPoint为界限,在前半部分只要找所有的TT_MIN为候选split,在后半部分找所有的TT_MAX为候选的split 。


sameSplitValue 变量的存在,因为有些三角面元的TT_MIN和TT_MAX 在投影坐标上是重合的,因此就忽略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值