Javascript 我想把一堆平面映射到一个球体上,它可以工作,但是有一些未被发现的bug

Javascript 我想把一堆平面映射到一个球体上,它可以工作,但是有一些未被发现的bug,javascript,math,three.js,projection,Javascript,Math,Three.js,Projection,我目前正在为学校做一个项目,我必须制作一个球体,在这个球体上我必须映射5000个图像 我这里有一个平面投影,它是我要映射的对象 这里我有一个球形模型 我使用的是three.JS和墨卡托投影原理,但是你可以看到图像旋转,我不知道如何修复 我已经搜索了一段时间,但什么也没找到 这是我用来放置所有图像的代码 drawMeridianCells(scene,rayon) { var startCollPos = 5; var currentCounter = 0; var cur

我目前正在为学校做一个项目,我必须制作一个球体,在这个球体上我必须映射5000个图像

我这里有一个平面投影,它是我要映射的对象

这里我有一个球形模型

我使用的是three.JS和墨卡托投影原理,但是你可以看到图像旋转,我不知道如何修复

我已经搜索了一段时间,但什么也没找到

这是我用来放置所有图像的代码

drawMeridianCells(scene,rayon)
{
    var startCollPos = 5;
    var currentCounter = 0;
    var currentRow = 0;

    var counter = 0;


    let cell = new Array(this._totalCells);
    var rows = [4,3,4,4,6,6,6,6,4,4,3,4];
    var col = [2,4,6,8,10,12,12,10,8,6,4,2];
    var res = Number(col[counter]) * Number(rows[counter])  ;

    var currentIndex = 0;

    var north = true;


    for(var i = 0; i < this._totalCells; i++)
    {
        if(currentCounter >= col[counter])
        {       
            currentRow++;                                        
            currentCounter = 0;     
        }     


        if( currentIndex >= res)
        {           
            counter++;  
            res = Number(col[counter]) * Number(rows[counter])  ;                        
            currentIndex = 0;

            if(north)
                startCollPos--;
            else
                startCollPos++;

            if(startCollPos < 0)
            {
                startCollPos =0;
                north =  false;
            }
        }

        //spherical W/ mercator projection
        //https://stackoverflow.com/questions/12732590/how-map-2d-grid-points-x-y-onto-sphere-as-3d-points-x-y-z

        var long = (this._posX  +(currentCounter+startCollPos) * (this._celW+2))/rayon;
        var lat = 2*Math.atan(Math.exp(  (this._posY + (currentRow) * (this._celH*2))/rayon )) - Math.PI/2;

        var _x = rayon* (Math.cos(lat) * Math.cos(long)) ;
        var _y = rayon* (Math.cos(lat)  * Math.sin(long));
        var _z = rayon* (Math.sin(lat));

        cell[i] = new Square(new Point(_x,_y,_z ),
        this._celW  ,
        this._celH  );


        //flat
        /*cell[i] = new Square(   new Point((this._posX  +(currentCounter+startCollPos) * (this._celW)),
        (this._posY + (currentRow) * (this._celH)),0 ),
        this._celW,
        this._celH  );*/

        cell[i].drawSquare(scene,Math.random() *0xffffff);     
        cell[i].lookAtZero();

        currentCounter++;        
        currentIndex++;   

    }         
}
drawing单元(场景、人造丝)
{
var startCollPos=5;
var currentCounter=0;
var currentRow=0;
var计数器=0;
let cell=新数组(此为._totalCells);
var行=[4,3,4,4,6,6,6,6,4,4,3,4];
var col=[2,4,6,8,10,12,12,10,8,6,4,2];
var res=编号(列[计数器])*编号(行[计数器]);
var currentIndex=0;
var north=真;
对于(var i=0;i=列[计数器])
{       
currentRow++;
电流计数器=0;
}     
如果(当前索引>=res)
{           
计数器++;
res=编号(列[计数器])*编号(行[计数器]);
currentIndex=0;
if(北)
startCollPos--;
其他的
startCollPos++;
如果(startCollPos<0)
{
startCollPos=0;
北=假;
}
}
//球面W/mercator投影
//https://stackoverflow.com/questions/12732590/how-map-2d-grid-points-x-y-onto-sphere-as-3d-points-x-y-z
var long=(此._posX+(currentCounter+startCollPos)*(此._celW+2))/人造丝;
var lat=2*Math.atan(Math.exp((this._posY+(currentRow)*(this._celH*2))/rayon))-Math.PI/2;
var_x=人造丝*(数学cos(lat)*数学cos(long));
var_y=人造丝*(数学cos(lat)*数学sin(long));
var_z=人造丝*(数学sin(lat));
单元[i]=新正方形(新点(x,y,z),
这个,
这个(u celH),;
//平坦的
/*单元格[i]=新的正方形(新的点((this._posX+(currentCounter+startCollPos)*(this._celW)),
(此位置+(当前行)*(此位置)),0),
这个,
这个(u celH),*/
单元格[i].drawSquare(场景,Math.random()*0xffffff);
单元格[i].lookAtZero();
电流计数器++;
currentIndex++;
}         
}

我希望我已经足够清楚了

我认为问题可能在
Square
构造函数中,或者可能在
drawSquare()
中。lookAtZero()`方法也可能是可疑的,我认为这会将法线旋转到零,但对于如何旋转形状来实现这一点,这是不明确的

在构建正方形时,需要确保一条边沿纬度线,另一条边沿经度线。 从

var x0 = rayon* (Math.cos(lat) * Math.cos(long)) ;
var y0 = rayon* (Math.cos(lat)  * Math.sin(long));
var z0 = rayon* (Math.sin(lat));
作为广场的中心。水平切线将为

tx = -Math.sin(long)
ty = Math.cos(long)
tz = 0
和沿纬度线的切线

ux = -Math.cos(lat) * Math.cos(long)
uy = -Math.cos(lat) * Math.cos(long)
uz = Math.sin(lat)
这些是通过分别对long和lat进行微分得到的。它们应该是单位长度向量

然后可以形成一个带有点的矩形

x0 +/- celW * tx  +/-  celH * ux
y0 +/- celW * ty  +/-  celH * uy
z0 +/- celW * tz  +/-  celH * uz
另一种方法是通过增加lat和long参数来形成点

var x2 = rayon* (Math.cos(lat + lat_inc) * Math.cos(long + long_inc)) ;
var y2 = rayon* (Math.cos(lat + lat_inc) * Math.sin(long + long_inc));
var z2 = rayon* (Math.sin(lat + lat_inc));

这会给你一个梯形而不是矩形。

我尝试了很多不同的公式来看看问题是什么,但它不会改变任何东西,你之前发布的关于blilboards的内容似乎很好,但在计算5000架飞机时有点繁重。我想将量子与纬度和经度相比较,我成功地做到了,我只需要切换X和Z,如果没有你的评论,我永远不会想到这样做,我想剩下的就由我决定了谢谢!写了一个小错误,更像是切换Y和Z