Reputation: 31
I am currently working on a project for school where I have to make a sphere where I have to Map ~5000 images on it
I have here a flat projection from what I want to map
And here I have a spherical model of it
I am using three.JS, and the principe of the mercator projection but as you can see Images rotate And I dont know how to fix that.
And I have been searching for a while and I found nothing
And here is the code I use to place all my images
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++;
}
}
I hope I have been clear enough
Upvotes: 1
Views: 595
Reputation: 7824
I think the problem might be in the Square
constructor, or possibly in drawSquare()
. The lookAtZero()` method is also likely to be suspect, I think this rotates the normal to point to zero but is ambiguous over quite how the shape is rotated to make this happen.
When you are constructing the squares you need to ensure one edge is along a line of latitude and one is along a line of longitude. Starting with
var x0 = rayon* (Math.cos(lat) * Math.cos(long)) ;
var y0 = rayon* (Math.cos(lat) * Math.sin(long));
var z0 = rayon* (Math.sin(lat));
as the centre of the square. The horizontal tangent will be
tx = -Math.sin(long)
ty = Math.cos(long)
tz = 0
and the tangent along the line of latitude
ux = -Math.cos(lat) * Math.cos(long)
uy = -Math.cos(lat) * Math.cos(long)
uz = Math.sin(lat)
These are obtained by differentiating with respect to long and lat respectively. They should be unit length vectors.
You can then form a rectangle with point
x0 +/- celW * tx +/- celH * ux
y0 +/- celW * ty +/- celH * uy
z0 +/- celW * tz +/- celH * uz
The other way to do it would be to form points by incrementing the lat and long parameters
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));
this would give you a trapezium rather than a rectangle though.
Upvotes: 2