I am trying to implement my own sphere based on a geospatial dataset.
I import a GeoJSON file that describes a grid which covers the entire earth. The coordinates for each grid cell (a grid cell has more than 3 verticies!) are given as latitude (-90 90) and longitude (-180 180). These polar coordinates are transformed to cartesian coordinates x,y,z and send to the below function:
function triangulate_grid(vertices, color) {
//http://blog.cjgammon.com/threejs-geometry
var holes = [];
var triangles, mesh;
var geometry = new THREE.Geometry();
var color = new THREE.Color(color[0], color[1], color[2]);
//http://jsfiddle.net/RnFqz/22/
var material = new THREE.MeshPhongMaterial({
color: color,
// FlatShading: THREE.FlatShading,
// side: THREE.DoubleSide,
// side: THREE.BackSide,
side: THREE.FrontSide,
wireframe: false,
transparent: false,
vertexColors: THREE.FaceColors, // CHANGED
// overdraw: true
});
var materialIndex = 0; //optional
geometry.vertices = vertices;
triangles = THREE.ShapeUtils.triangulateShape(vertices, holes);
for (var i = 0; i < triangles.length; i++) {
face = new THREE.Face3(triangles[i][0], triangles[i][1], triangles[i][2])
face.color = color;
geometry.faces.push(face);
}
geometry.computeFaceNormals();
geometry.computeVertexNormals();
mesh = new THREE.Mesh(geometry, material);
//https://stackoverflow.com/questions/28848863/threejs-how-to-rotate-around-objects-own-center-instead-of-world-center
mesh.rotation.x = -90;
scene.add(mesh)
}
The sphere that is drawn looks like this:
It would be easier to see if you could rotate it yourself. But what is happening is, that I see the surface of the faces of the northern hemisphere as an astronaut would see it (from above), while the faces of the southern hemisphere can only be seen by looking through the earth. It looks like the equator is 'flipping' the faces with latitude coordinates 0 to -90 to only show the backside.
I am using this function to make the coordinate transformation.
//https://bl.ocks.org/mbostock/2b85250396c17a79155302f91ec21224
function vertex(point) {
var lambda = (point[0]) * Math.PI / 180, // lon
phi = (point[1]) * Math.PI / 180, //lat
cosPhi = Math.cos(phi);
var radius = 1;
vector = new THREE.Vector3(
radius * cosPhi * Math.cos(lambda),
radius * cosPhi * Math.sin(lambda),
radius * Math.sin(phi)
);
// vector.applyAxisAngle( 0, 90 );
return vector
}
I have used THREE.DoubleSide
, but that solves the problem only partially. First, I think it is not necessary and only takes ressources and second, there are still artifacts at the equator. See the upper left corner of the image.
Question: How to draw all faces on the nothern and southern hemisphere, so I can see the surface and not look through?