0

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
I have here a flat projection from what I want to map

And here I have a spherical model of it
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

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • I am trying a lot of different formulas to see what the problem is but then It won't change anything, and the previous thing you posted about blilboards seems to be good but a bit heavy in calculation for 5000 planes. – Emmanuel janssens Sep 11 '17 at 13:03
  • 1
    I wanted to aling the quands to the latitude and longitude, I managed to do that, I had to switch only the X and Z , without your comment I would never have though of doing that I think the rest is up to me thank you ! – Emmanuel janssens Sep 11 '17 at 13:33
  • Wrote a little error it's more like switching the Y and the Z – Emmanuel janssens Sep 11 '17 at 13:55

1 Answers1

1

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.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Salix alba
  • 7,536
  • 2
  • 32
  • 38