30

About starting with three.js to making a 3d earth (Part 5: Vector earth with dots)

The renderings of this article:
image.png

Note: I have poor painting skills hahahahahaha...

1. Basic concepts of geojson

In this article, we are going to draw a vector globe. Then we first need to know what the vector globe is made of. For example, if we want to draw'China', then we only need to know the coordinates of all the points on the border of China, and then link these points one by one. It is the outline of China. Because each point is very close, although we use straight lines to link, we can still form a smooth spherical effect. Simply understand that geojson is such a set of data, which contains all the necessary to draw the outline of each country. you understand the information of 16090f0f94de90 points in depth, you will find that geojson , but we will not discuss it when we mainly talk about drawing the most basic country outline. Let’s draw a flat map first.
This is an article that I wrote before that introduces geojson in detail. If you are interested, you can learn about it. It will help you understand the map better: remember a front-end "Unveiling the mystery of drawing maps" sharing session .
The mathematical knowledge designed in this chapter is all elementary, and later will involve matrix. I will explain it to you in the most popular way at that time, not just the concept but the most popular way for your convenience. Understand, there will be detailed explanations and illustrations latitude and longitude to xyz later in this article.

2. Latitude and Longitude

The concepts here are very basic and important, so please read them carefully if you are not familiar with it.

longitude

Longitude is the number of degrees east or west of a location on the earth from a north-south line called the prime meridian. The longitude of the prime meridian is 0°, and the longitudes of other places on the earth are east to 180° or west to 180°. The line of the prime meridian is selected by people, and there is a time zone every 15° (time zone caused The bug I shared before: time zone related bug ).
As shown in the figure, the computer uses the positive and negative numbers of to distinguish the east and west longitudes, the east longitude is positive west longitude is negative numbers, and the degree range is [-180, 180] .
image.png

latitude

Draw a normal line through a point on the ellipsoid. The line-face angle between the normal line of the point and the equatorial plane is between 0 and 90 degrees. The latitude of a point located north of the equator is called north latitude and is denoted as N; the latitude of a point located south of the equator is called south latitude and is denoted as S.
As shown in the figure, in the computer, the positive and negative numbers of are used to distinguish the north and south latitudes, the north latitude is the south latitude is negative number, and the degree range is [-90, 90] .

image.png

Extended knowledge: measuring latitude and longitude

At any place on the earth, as long as there is a watch, a bamboo pole, and a tape measure, you can know the local latitude and longitude. But the table must be proofread with the country's standard time, and the specific method can be tested on Baidu Baike if you are interested.

3. Remember trigonometric functions?

Don't be afraid that we won't have to recite it after graduation for so long, as long as we know how to use it, let's review it together:
image.png

nameformula
sin(∠A)a/c
cos(∠A)b/c
tan(∠A)a/b
  • Because geojson is latitude and longitude, we will use it to convert the latitude and longitude into coordinates. Of course, geojson can also store coordinates directly.

Four. Radian

That is, two rays shoot out from the center of the circle to the circumference, forming an arc with an included angle and the included angle directly opposite. When the length of the arc is exactly equal to the radius of the circle, the radian of the angle between the two rays is 1.
image.png

V. Implementation in the front-end code

If you take it for granted that writing Math.sin(30) directly in the front-end code will output 0.5 then you are wrong.
image.png
Because in our Math operation, what needs to be input is radians, which is why I have to repeat the concept of radians above, so sin(30) we have to write Math.sin(30 * Math.PI / 180) like this.
image.png

In order to make it easier for everyone to understand, I still write down the derivation process
  1. 1 radian is the angle corresponding to the arc length as the radius. It is known that the circumference of a circle is 2πr .
  2. It can be concluded that a circle has a total of 2πr ÷ r radians, that is, radians is a circle.
  3. A circle has an angle of 360°, and the corresponding radian of an angle of 1° is ÷ 360 , which is π/180 .
  4. So the sin(30°) mentioned above is Math.sin(30 * Math.PI / 180)

6. Draw a flat world

After learning this, I geojson that you have already understood the related concepts of 06090f0f94e1c5. A country may have multiple contours and do not border each other. We need to process them into an array, which is this sentence country.geometry.type === "Polygon" .
/cc_map_3d_pro/src/components/cc_map.vue

import worldGeo from "../assets/geojson/world.geo";
.../
    initEarth() {
      const R = envConifg.r;
      worldGeo.features.forEach((country) => {
        if (country.geometry.type === "Polygon") {
          country.geometry.coordinates = [country.geometry.coordinates];
        }
        var line = countryLine(R, country.geometry.coordinates);
        this.scene.add(line);
      });
    },

The world's geojson can be found in my project github view .

  • Above we passed the radius and points to the countryLine method for processing, and added them to the environment. After , we will put all the graphic objects into different groups. Here, we will not spread the knowledge points.

7. Use to draw line

/cc_map_3d_pro/src/utils/countryLine.js method, we specifically draw the outline of the country.

import * as THREE from 'three';

function countryLine(R, polygonArr) {
  let group = new THREE.Group();
  polygonArr.forEach(polygon => {
    let pointArr = [];
    polygon[0].forEach(elem => {
      pointArr.push(elem[0], elem[1], 0)
    });
    group.add(line(pointArr));
  });
  return group;
}
new THREE.Group()

In three.js Chinese network connection off to original words, and it is almost Object3D are the same, so that the purpose of the grammatical object group in the structure more clearly.

Suppose I now generate two cubes geometry , named a and b respectively, then I don’t use the following writing

this.scene.add(a);
this.scene.add(b);

Instead, you can create a group:

const group = new THREE.Group();
group.add(a)
group.add(b)
this.scene.add(group);

In more detail, we will talk in detail in the follow-up chapters of .

  • Above we rely on a line , this method is an important knowledge point this time.

8. Drawing line segments is not line (06090f0f94e345 method)

function line(pointArr) {
  let geometry = new THREE.BufferGeometry();
  let vertices = new Float32Array(pointArr);
  let attribue = new THREE.BufferAttribute(vertices, 3);
  geometry.attributes.position = attribue;
  let material = new THREE.LineBasicMaterial({
    color: 0x00aaaa //线条颜色
  });
  let line = new THREE.LineLoop(geometry, material);
  return line;
}
1. The incoming parameter pointArr ;

countryLine method, here is [x1, y1, z1, x2, y2, z2, x3, y3, z3] . You may feel that this form does not conform to js , but it conforms to the idea of webgl or svg webgl will be explained later when the shader of It will make you understand, don’t study too much now because the knowledge here is very deep.

2. new THREE.BufferGeometry();

Using BufferGeometry can effectively reduce GPU . A country has an average of several hundred sets of points, so using ordinary Geometry will become very stuck. Please rest assured that I will unify the related pages say again, where you can temporarily understood as a three.js converted data stream.

3. new Float32Array();

js native knowledge : Float32Array type array represents a floating-point array with a platform byte order of 32 bits (corresponding to the C floating-point data type), Float32Array has better performance when the amount of data is large, and is more in line with webgl Parameter standards, about this kind of TypedArray is a big topic, I will talk about the shader chapter.

4. new THREE.BufferAttribute();

This class is used to store the attributes associated with BufferGeometry (such as vertex position vector, face index, normal vector, color value, UV coordinates and any custom attributes), and use BufferAttribute to transfer data to the GPU more efficiently.

  1. The first parameter: is the data source, which is the coordinate array processed above.
  2. The second parameter: data is stored as a vector of arbitrary length, where 3 is transmitted, to be understood that for each of a set of three data, i.e. x1, y1, z1 group, x2, y2, z2 a group, and so on.
5. new THREE.LineBasicMaterial();

The basic line material, that is, professionally drawn lines, you can adjust the color and thickness, and the appearance of the thread.

6. geometry.attributes.position = attribue

This writing looks very rude , it means to replace the position information of the graph with the array we processed, which is to set the position of each point for the graph.

7. new THREE.LineLoop();

loop line is the line that connects end to end, just like when we create a rectangle every time, this method creates a loop line.

Because we passed z-axis to 0, so the following flat map
image.png
image.png

Nine. Longitude and latitude conversion to Cartesian coordinate system (theory)

There are also many libraries that directly make this kind of flat earth, but our series of articles is to learn about the round earth, so we have to convert latitude and longitude coordinates into spherical coordinates.
We will start the study one by one x y z

The simplest y-axis

y-axis of 16090f0f94e58e is actually only related to the latitude . The simplest thing can be found as shown in the figure below:
image.png

  • A point on the sphere, the distance between this point and the center of the circle is the radius of the circle r , and now we require the distance from this point to zy plane.

image.png

  • This point x and z is not necessarily 0, so as not necessarily vertical fall x-axis, but no matter how this segment for vertical and angle xz plane will not change, and this clip The angle is latitude, so we know that the length of the hypotenuse is r , the trigonometric function sin (latitude) = opposite side/hypotenuse, the side of is 16090f0f94e636 y-axis value, we multiply both the left and right sides by r , and finally:
sin(纬度) 乘 r = y
x-axis that needs to be calculated

The x-axis needs to be calculated step by step, and each step has a diagram:

image.png
As demonstrated above, we can regard this point as a cube, a cube with a known diagonal length of r , and then we can take this cube out for study alone, which can be separated from this coordinate system.

image.png

Now that the diagonal length of the cube is r and the height is y-axis coordinate, then use latitude to find the bottom diagonal.

image.png
We use and demand similar manner as the y-axis is obtained x1 length:

cos(纬度) 乘 r = x1

image.png

It can be seen from the figure that longitude is the angle of the diagonal line extending along the yz plane sin to find the length.

sin(经度) * x1 = x

Bring in the formula for x1:

x = sin(经度) 乘 cos(纬度)
z-axis corresponding to x

image.png
The same principle as x, but here we use cos 's edge than the hypotenuse.

z = cos(经度) 乘 cos(纬度)

X. Latitude and longitude conversion to Cartesian coordinate system (code)

Don't forget in actual combat, first latitude and longitude to 16090f0f94e7b8 radians.

// 经纬度转坐标
function lon2xyz(R, longitude, latitude) {
    const lon = longitude * Math.PI / 180;
    const lat = latitude * Math.PI / 180;
    const x = R * Math.cos(lat) * Math.sin(lon);
    const y = R * Math.sin(lat);
    const z = R * Math.cos(lon) * Math.cos(lat);
    return { x, y, z };
}
export default lon2xyz;
Some other tutorials

Some other tutorials will require longitude to be reversed, and x and z are reversed. That way of writing is not recommended, we just follow the normal thinking.

11. The round earth

After unremitting efforts, we finally saved the 16090f0f94e815 ball, let's see what he
image.png
From the picture above, we can see that there are actually many problems. For example, the lines cover each other. We should make the earth invisible, and temporarily the earth cannot be clicked, and the realism is not enough. It is really a long way to go. .

end

The next article will explain how to make points on the map and add halo to the earth and other effects. By this time, this series of articles is less than half. The knowledge of ray picking countries and triangle throwing points will also be paid to the surface, wonderful Interesting knowledge is still behind, I hope to progress with you.


lulu_up
5.7k 声望6.9k 粉丝

自信自律, 终身学习, 创业者