1

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: enter image description here

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. enter image description here

Question: How to draw all faces on the nothern and southern hemisphere, so I can see the surface and not look through?

Update: Added a cube to make it more clear. enter image description here

Michael
  • 1,627
  • 1
  • 19
  • 29
  • 3
    Likely, it is the winding order. The vertices of each face must have counterclockwise winding order when the face is facing towards you. – WestLangley Nov 14 '18 at 12:32
  • What arguments are you passing to `triangulate_grid()` when you call it? It seems like a large portion of your code is missing from the question. – M - Nov 14 '18 at 22:50
  • @Marquizzo, the vertices that are passed to ```triangulate_grid()``` are an array of 6 ```THREE.Vector3(x,y,z)```. – Michael Nov 14 '18 at 23:53
  • @WestLangley, I have checked the winding order of all faces, it is consistent clockwise. – Michael Nov 14 '18 at 23:55
  • I ended up replacing ```triangles = THREE.ShapeUtils.triangulateShape(vertices, holes);``` with my own function and adding a center vertex to calculate the faces. It works now. – Michael Nov 14 '18 at 23:58
  • 1
    @Michael counterclockwise, not clockwise – WestLangley Nov 15 '18 at 00:38

0 Answers0