【问题标题】:2d Ray Tracing - filling the view2d 光线追踪 - 填充视图
【发布时间】:2023-03-27 16:45:01
【问题描述】:

我的 2d 光线追踪器一直运行良好,直到我按角度(特别是弧度)对计算出的光线进行排序。我认为这与 tan 的行为方式有关,但我不确定。用已知的 x,y 对碰撞和起始点的角度进行排序的最佳方法是什么?我已经断断续续地解决同一个问题 2 周,并且几乎尝试了所有方法。

我现在可以在这里上传图片: 如果您想摆弄它,这是有罪的代码:

function sortByAngle(pos){
for (var i = viewFeild.length - 1; i >= 0; i --) {      
    viewFeild[i][3] = Math.atan((viewFeild[i][4]-pos.y)/(viewFeild[i][0]-pos.x));
    if(viewFeild[i][5]<pos.y)
        viewFeild[i][6] = viewFeild[i][7]*-1-4;

    if (viewFeild[i][8]<0) {viewFeild[i][9]+=2};
};

viewFeild.sort(function(a,b){return a[2]-b[2]});
}

function fillView(pos) {

for (var i = viewFeild.length - 1; i >= 0; i--) {
    //console.log(i+"     "+viewFeild[i][10] + "   " + viewFeild[(i+1)%viewFeild.length][11])
    //console.log(viewFeild.length)
    ctx.beginPath();
    ctx.moveTo(pos.x, pos.y);
    ctx.lineTo(viewFeild[i][0]+pos.x, viewFeild[i][12]+pos.y);
    ctx.lineTo(viewFeild[(i+1)%viewFeild.length][0]+pos.x, viewFeild[(i+1)%viewFeild.length][13]+pos.y);
    ctx.closePath();
    ctx.fillStyle = "rgba(100, " + 35*i  + ", 100, .6)";
    ctx.fill();
};
}

这是包含整个 js 代码和 html 的 google doc(html 在 js 之后) https://docs.google.com/document/d/12chxLiaj9gz-irlM0VdZs-BNoNqoMbz5AS0Dm0CpXfI/edit?usp=sharing

【问题讨论】:

    标签: javascript canvas trigonometry raytracing radians


    【解决方案1】:

    首先要做的是澄清你的代码。
    1)您不需要以相反的顺序填充数组。
    2) 使用 atan2 - 我不明白你处理弧度的方式...
    3) 缓存您将重复使用的数组元素。
    4) 不要为每个排序创建一个排序函数。
    5)如果排序正确,就不需要倒序显示了。

    一旦情况更清楚,我发现您使用字段 3、5 或 6 作为您的点的 y 很奇怪。我会说 y 数据的一个偏移量就足够了 ;-)

    function sortByAngle(center) {
        for (var i = 0 ; i<viewFeild.length ; i++) {
            var thisField = viewFeild[i] ; 
            thisField[2] = Math.atan2( thisField[3] - center.y) 
                                        , (thisField[0] - center.x));
        };
        viewFeild.sort(sortOnSecondItem);
    }
    
    function fillView(pos) {
        for (var i = 0 ; i<viewFeild.length ; i++) {
            var thisField = viewFeild[i] ; 
            var nextField = (i==viewFeild.length-1) ?
                                viewFeild[0] 
                              : viewFeild[i+1] ;
            ctx.beginPath();
            ctx.moveTo(pos.x, pos.y);
            ctx.lineTo(thisField[0] + pos.x, thisField[5] + pos.y);
            ctx.lineTo(nextField[0] + pos.x, nextField[6] + pos.y);
            ctx.closePath();
            ctx.fillStyle = "rgba(100, " + 35 * i + ", 100, .6)";
            ctx.fill();
        };
    }
    
    function sortOnSecondItem(a,b) { return a[2] - b[2] }
    

    【讨论】:

    • 嗯,这很奇怪,因为原始代码使用 [1] 作为 y 点,如 google doc 中所见,可能只是错过了转录,谢谢 :)
    • 那么上面的代码是否应该解决问题(当我尝试时它仍然有同样的问题,我认为是因为我们仍在使用 Math.atan2())?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 2019-11-29
    相关资源
    最近更新 更多