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

goh*_*goh 10 c++ algorithm geometry raycasting

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

  1. 穿过深绿色的盒子,我会分配成本c
  2. 在深绿色的盒子上,我将分配成本d
  3. 落在红色区域我将分配成本e
  4. 不与深绿色的盒子相交而不是在红色盒子里,成本为f
  5. d < f < c < e

在此输入图像描述

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

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

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

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;
Run Code Online (Sandbox Code Playgroud)

计算成本的功能:

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);
    }
Run Code Online (Sandbox Code Playgroud)

Aco*_*gua 2

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

所以我的建议如下:让另一个std::vector<VRay*>在开始时为空,并有第二个 sum 变量。在第一次运行时,按实际情况计算成本。此外,对于每条光线,确定在改变 DGR 时它是否可能发生变化。

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

如何决定光线是否会改变成本?好吧,那些没有跨越红色矩形的人当然不会。那些以浅绿色矩形结尾的以及那些同时穿过浅绿色和红色矩形的也不会。因此,相关光线是那些在红色矩形内结束但不在浅绿色矩形内的光线,另外还有那些完全穿过红色矩形但不与浅绿色矩形相交的光线。

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