Javascript 我想把一堆平面映射到一个球体上,它可以工作,但是有一些未被发现的bug
我目前正在为学校做一个项目,我必须制作一个球体,在这个球体上我必须映射5000个图像 我这里有一个平面投影,它是我要映射的对象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
这里我有一个球形模型
我使用的是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