更改矩形大小时重新计算光线跟踪/投射成本

时间:2017-02-24 10:29:47

标签: c++ algorithm geometry raycasting

我有一系列“光线”,我需要测量与下面矩形框相关的成本。外部红色框总是比深绿色框大1米,浅绿色框比深绿色框小10厘米。如果射线

  1. 通过暗绿框,我将分配成本c
  2. ands on the dark green box我将指定成本d
  3. 降落在我指定的红色区域 成本e
  4. 不会与深绿色的盒子相交而不会落入红色框中,成本为f
  5. d < f < c < e
  6. enter image description here

    我目前有以下数据结构和函数来计算成本。我需要计算给定矩形的成本(由4 xy坐标表示),但同时,找到深绿色矩形的近似/局部最佳长度/宽度(即收缩或通过固定矩形的最近角来增大尺寸,使成本最小。

    一个具体的例子是下面的截图。较小的矩形对应于图中的深绿色框。绿线是成本为d的光线,黄线为成本f,绿松石线为成本为c的光线。如果我固定内部矩形的左上角并减小宽度,我可以将turqoise射线从成本c减少到f。
    enter image description here

    我的问题是,我不知道应该如何改变我的代码或改变我的数据结构,这样我才能通过重新计算受影响的光线找到最佳尺寸(即不再遍历所有光线)。

    struct VRay{
        float range, x, y;
        enum RayType{ PASSTHROUGH, FREE, SURFACE, OCCLUDED, UNIFORM};
        RayType r;
    };
    struct VScan{
        VRay rays[401];
        int closestIdx;
        int firstIdx;
        int lastIdx;
    } vscan;
    

    计算成本的功能:

    for (int i = 0; i < 401; i++){
           VRay& r = vscan.rays[i];
    
           Vector2f cray(r.y, -r.x);
           bool ppBound = false;
           bool ppSurf = false;
           Vector2f vertex =  outBox.row(0);
           Vector2f vertexSurf = surface.row(0);
    
           float init = cray.dot(vertex);
           float initSurf = cray.dot(vertexSurf);
           //this part finds whether ray intersects rectangle or not 
           for (int j = 1; j < 4; j++){
                Vector2f v2 = outBox.row(j);
                Vector2f vSurf =  surface.row(j);
    
                float i2 = cray.dot(v2);
                float iSurf = cray.dot(vSurf);
    
                if (i2 * init < 0){
                    ppBound =  true;
                }
    
                if (iSurf * initSurf < 0){
                    ppSurf = true;
                }
           }
    
           //ray does not intersect all rectangles
           if (!ppBound){
              z += log(1/100.);
              continue;
           }
    
            //ray is inside red box
            if (inPolygon(outBox, r)){
                //ray inside dark green box 
                if (inPolygon(surface, r)){
                    //ray inside light green box
                    if (inPolygon(inBox,r))
                        c  = passTCost;
                    else
                        c = surfaceCost;
                }
                else{
                    c = freeCost; //free space
                }
            }
            else if (ppSurf){
                c = passTCost; //before all boxes
            }
            else { //ray does not intersect dark green box
                z += log(1/100.);
                continue;
            }
    
            z += -(c * c)/(2 * deviation * deviation);
        }
    

2 个答案:

答案 0 :(得分:2)

我是否认为光线永远不会落在浅绿色的盒子里?即光线到达浅绿色区域时会停止吗?是否有任何规则确定光线是否落在红色区域,深绿色区域或是否穿过它们?

如果这些规则与汽车的尺寸无关,而只取决于光线“终点”的相对位置,例如:如果汽车表面中间的光线始终落在汽车周围的自由空间上,那么光线数量与成本dc或{{1}的关系不依赖于汽车的大小。成本为e(标记为黄色)的光线数量就是光线的其余部分,即没有成本fdc的光线。< / p>

这意味着,在第一步中,计算成本的最佳(最小)总和,给定e / d / c的成本的固定比率并知道剩余部分光线的成本为e

示例:您有5%的光线成本为f(绿松石线),10%的光线成本为c(红线),40%的光线成本为{{1} (绿线)和45%的成本为e的光线(黄线)。因此,对于成本为d的每条光线,您有两条成本为f的光线和八条成本为c的光线。剩下的所有光线都花费e

- &GT;让d为成本为f的光线数量,然后总费用为:x

现在找到这个函数的最小值(这很简单,因为它是一个线性函数,但可能你对汽车的大小有一些限制),并使用生成的c来计算你的大小汽车:如果你在开始时有例如成本为1*c*x + 2*e*x + 8*d*x + (totalNumberOfRays - (1+2+8)*x) * f的10条射线,结果x为5,您必须找到仅产生5条成本c的汽车尺寸,即汽车宽度和长度均应为乘以0.5。

现在,我唯一希望的是,我的假设是正确的: - )

(我想到的其他选项,如果我的假设是错误的,就是以某种方式将光线组合在一起,并且只对每个组进行计算)

答案 1 :(得分:2)

如果我理解你正确,你想要改变深绿色矩形的大小,使它保留一个与浅绿色矩形的公共中心,两者的边缘保持平行。深绿色矩形在任何点都不会留下红色矩形,永远不会小于浅绿色矩形。红色和浅绿色矩形保持不变。你只想重新计算那些可能会改变成本的光线,如果你改变了深绿色矩形(DGR从现在开始......)。

所以我的主张如下: 让另一个std::vector<VRay*>在开始时为空,以及第二个和变量。在第一次运行中,像您一样计算您的成本。此外,对于每条光线,确定在改变DGR时它是否会发生变化。

如果可以,将指针添加到上面的向量,否则,将其当前成本添加到第二个总和。从现在开始,您只需在指针向量中重新计算这些光线,并将预先计算的其他光线总和添加到此新总和中。

如果光线可能会改变成本,如何决定?那么,那些没有穿过红色矩形的人当然不会。以浅绿色矩形结尾的那些,以及那些穿过浅绿色和红色矩形的那些都没有。所以相关的光线是那些在红色矩形内部结束的光线,但不是在浅绿色光线内,另外那些光线完全穿过红色光线但不与浅绿色光线相交。

如果你考虑最大DGR(如果它不一定与红色DGR平行),可以收集进一步的优化:那些不与这个最大矩形相交或在它前面结束的线也不会改变。