更改矩形大小时重新计算射线 tracing/casting 成本

recalculate ray tracing/casting costs when changing size of rectangle

我有一个 "rays" 的数组,我需要根据下面的矩形框来衡量成本。外层红色框总是比深绿色框大 1m,浅绿色框总是比深绿色框小 10cm。如果射线

  1. 穿过深绿色框我会分配成本 c
  2. ands 在深绿色框上我会分配成本 d
  3. 落在我要指定的红色区域 成本 e
  4. 不与深绿色方框相交且不落在红色方框内,成本f
  5. d < f < c < e

我目前有以下数据结构和函数来计算成本。我需要计算给定矩形的成本(由 4 个 xy 坐标表示),但同时找到 approximate/local 最优 length/width深绿色矩形(即通过固定矩形的最近角来缩小或增大尺寸)使得成本最小。

一个具体的例子是下面的截图。较小的矩形对应于图中的深绿色框。绿线是成本为 d 的光线,黄线是成本为 f 的光线,蓝绿色线是成本为 c 的光线。如果我固定内部矩形的左上角并减小宽度,我可以将绿松石射线的成本从 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;

成本计算函数:

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);
    }

光线永远不会落在浅绿色框中,我说得对吗?即光线到达浅绿色区域时停止?是否有任何规则可以确定光线是落在红色区域、深绿色区域还是同时穿过它们?

如果这些规则与车的大小无关,而只取决于射线"end point"的相对位置,例如如果射到汽车表面中间的光线总是落在汽车周围的自由 space 上,则光线数量与成本 dce 与汽车的大小无关。成本为 f(标记为黄色)的光线数量只是其余光线,即没有成本 dce 的光线。

这意味着在第一步中,计算最佳(最小)成本总和,给定 d/c/e 的恒定成本比率并且知道其余射线的成本为 f.

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

-> 设 x 为成本为 c 的射线数,则总成本为:1*c*x + 2*e*x + 8*d*x + (totalNumberOfRays - (1+2+8)*x) * f

现在找到这个函数的最小值(这很容易,因为它是一个线性函数,但可能你对你的车的尺寸有一些限制),并使用结果 x 来计算尺寸你的车:如果你一开始就有,例如10条射线,成本c,结果x为5,你必须找到只产生5条成本c的汽车尺寸,即汽车宽度和长度应分别为乘以 0.5.

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

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

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

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

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

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

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