How to plot country names on the globe, so the mes

2019-06-04 00:03发布

问题:

I'm trying to plot country names of the globe, so the text meshes will be aligned with the surface, but I'm failing to calculate proper rotations. For text I'm using THREE.TextGeometry. The name appears on the click of the mesh of the country at the point of intersection using raycasting. I'm lacking knowledge of how to turn these coordinates to proper rotation angles. I'm not posting my code, as it's complete mess and I believe for a knowldgeable person will be easier to explain how to achieve this in general.

Here is desired result:

回答1:

very interesting question.I have tried this way, we can regard the text as a plane. lets define a normal vector n from your sphere center(or position) to point on the sphere surface where you want to display text. I have a simple way to make normal vector right. 1. put the text mesh on sphere center. text.position.copy(sphere.position) 2. make text to the point on sphere surface, text.lookAt(point) 3.relocate text to the point. text.position.copy(point)



回答2:

The other solution, which I tried (and which, of course, is not the ultimate), based on this SO answer. The idea is to use the normal of the face you intersect with the raycaster.

  1. Obtain the point of intersection.
  2. Obtain the face of intersection.
  3. Obtain the normal of the face (2).
  4. Get the normal (3) in world coordinates.
  5. Set position of the text object as sum of point of intersection (1) and the normal in world coordinates (4).
  6. Set lookAt() vector of the text object as sum of its position (5) and the normal in world coordinates (4).

Seems long, but actually it makes not so much of code:

var PGHelper = new THREE.PolarGridHelper(...); // let's imagine it's your text object ;)
var PGlookAt = new THREE.Vector3(); // point of lookAt for the "text" object

var normalMatrix = new THREE.Matrix3();
var worldNormal = new THREE.Vector3();

and in the animation loop:

for ( var i = 0; i < intersects.length; i++ ) {
    normalMatrix.getNormalMatrix( intersects[i].object.matrixWorld );
    worldNormal.copy(intersects[i].face.normal).applyMatrix3( normalMatrix ).normalize();

    PGHelper.position.addVectors(intersects[i].point, worldNormal);
    PGlookAt.addVectors(PGHelper.position, worldNormal);
    PGHelper.lookAt(PGlookAt);
}

jsfiddle exmaple

The method works with meshes of any geometry (checked with spheres and boxes though ;) ). And I'm sure there are another better methods.