Master class "Christmas balls" made of paper with your own hands. Sphere of two triangles

Spherical triangle and its application.

spherical triangle- a geometric figure on the surface of a sphere, formed by the intersection of three large circles. Three large circles on the surface of a sphere that do not intersect at one point form eight spherical triangles. A spherical triangle, all sides of which are less than half of the great circle, is called Euler.

The side of a spherical triangle is measured by the value of the central angle based on it. The angle of a spherical triangle is measured by the value of the dihedral angle between the planes in which the sides of this angle lie. Relations between elements of spherical triangles are studied by spherical trigonometry.

Properties of a spherical triangle:

  1. In addition to the three conditions for the equality of flat triangles, one more is true for spherical triangles: two spherical triangles are equal if their corresponding angles are equal.
  2. For the sides of a spherical triangle, 3 triangle inequalities hold: each side is less than the sum of the other two sides and greater than their difference.
  3. The sum of all sides a + b + c is always less than 2πR.
  4. The quantity 2πR − (a + b + c) is called a spherical defect
  5. The sum of the angles of a spherical triangle s = α + β + γ is always less than 3π and greater than π
  6. The quantity is called spherical excess or spherical excess
  7. The area of ​​a spherical triangle is determined by the formula.
  8. Unlike a flat triangle, a spherical triangle can have two or even three 90° angles each.

Among all spherical polygons, the most interesting is the spherical triangle. Three great circles, intersecting in pairs at two points, form eight spherical triangles on the sphere. Knowing the elements (sides and angles) of one of them, you can determine the elements of all the others, therefore, consider the relationship between the elements of one of them, the one in which all sides are less than half the great circle. The sides of the triangle are measured by the flat angles of the trihedral angle OABS, the angles of the triangle are measured by the dihedral angles of the same trihedral angle, see Fig.

The properties of spherical triangles differ in many ways from the properties of triangles in the plane. So, to the well-known three cases of equality of rectilinear triangles, a fourth is added: two triangles ABC and A`B`C` are equal if the three angles PA = RA`, PB = PB`, PC = PC` are equal, respectively. Thus, similar triangles do not exist on the sphere; moreover, in spherical geometry there is no concept of similarity itself, since there are no transformations that change all distances by the same (not equal to 1) number of times. These features are associated with the violation of the Euclidean axiom about parallel lines and are also inherent in Lobachevsky's geometry. Triangles that have equal elements and different orientations are called symmetrical, such as, for example, triangles AC`C and BCC`

The sum of the angles of any spherical triangle is always greater than 180°. The difference RA + RV + RS - p \u003d d (measured in radians) - is a positive value and is called the spherical excess of a given spherical triangle. Area of ​​a spherical triangle: S = R2 d where R is the radius of the sphere and d is the spherical excess. This formula was first published by the Dutchman A. Girard in 1629 and named after him.

If we consider a diagon with angle a, then at 226 = 2p/n (n is an integer), the sphere can be cut into exactly n copies of such a digon, and the area of ​​the sphere is 4pR2 = 4p at R = 1, so the area of ​​the digon is 4p/n = 2a. This formula is also true for a = 2pt/n and, therefore, is true for all a. If we continue the sides of the spherical triangle ABC and express the area of ​​the sphere in terms of the areas of the diagons formed in this case with angles A, B, C and its own area, then we can come to the above Girard formula.

By a spherical triangle is meant a triangle on the surface of a sphere, composed of arcs of great circles - that is, such circles, the center of which is the center of the sphere. The angles of a spherical triangle are the angles between the tangents to its sides drawn at its vertices. Like the angles of a regular triangle, they range from 0 to 180°. Unlike a flat triangle, a spherical triangle does not have a sum of angles equal to 180°, but more: it is easy to verify this by considering, for example, a triangle formed by the arcs of two meridians and the equator on a globe: although the meridians converge at the pole, both of them are perpendicular to the equator, and so this triangle has two right angles!

A spherical triangle can have two right angles

Already the Indian Varahamihira (5th-6th centuries), the Arab mathematicians and astronomers from the 9th century. (Sabit ibn Korra, al-Battani), and among Western mathematicians, starting from Regiomontanus (XV century), there is a wonderful theorem on spherical triangles in various formulations. Here is how it can be formulated in modern notation:

cosa = cosbcosc + sinbsinccosA. The spherical cosine theorem is very important for both astronomy and geography. This theorem allows using the coordinates of two cities A and B to find the distance between them. In addition, the spherical cosine theorem helped mathematicians in Islamic countries in solving another practical problem: in a city with given coordinates, find the direction to the holy city of Mecca (every orthodox Muslim must pray five times a day in the direction of Mecca). When solving this problem, considering the city B as Mecca, it was required to find the angle A of the same triangle.

A page from the "Collection of Rules for the Science of Astronomy", 11th century, author unknown.

In astronomy, the spherical cosine theorem allows you to move from one coordinate system on the celestial sphere to another. Three such systems are most often used: in one, the equator is the celestial equator, and the poles are the poles of the world, around which the visible daily rotation of the luminaries occurs; at the other, the equator is the ecliptic - the circle along which the visible movement of the Sun against the background of stars takes place during the year; in the third, the role of the equator is played by the horizon, and the role of the poles is played by the zenith and nadir. In particular, thanks to the spherical cosine theorem, it is possible to calculate the height of the Sun above the horizon at different times and on different days of the year.

Sails in architecture - a spherical triangle, providing a transition from the square in terms of dome space to the circumference of the dome. Sail, pandative (from French pendentif) - part of the vault, an element of the dome structure, through which the transition from the rectangular base to the dome ceiling or its drum is made. The sail has the shape of a spherical triangle with its apex down and fills the space between the spring arches connecting the adjacent pillars of the domed square. The bases of the spherical triangles of the sails together form a circle and distribute the load of the dome along the perimeter of the arches.

Dome on sails sail painting

George Nelson

"The designer can relax and have some fun; the result can be a joke, fun. It's amazing how often this is very significant fun." George Nelson

George Nelson is an American designer, architect, critic and design theorist. (1908, Hartford, Connecticut - 1986, New York)

He designed lighting fixtures, clocks, furniture, packaging, and was engaged in exhibition design.

The most famous design projects of George Nelson are masterly stylization of geometric shapes in the spirit of op art or geometric abstractionism.

The designer builds the shape of his famous black chair on the basis of a spherical triangle, which was widely used in the architectural structures of domed structures. In particular, in Byzantine and Russian churches, such a spherical triangle was called a "sail". Thanks to the “sail”, a smooth transition from the dome support to the dome was carried out.

George Nelson (George Harold Nelson, 1908-1986)

Escher engraving

Concentric spheres. 1935. End engraving 24 by 24 cm.

Four hollow concentric spheres are illuminated by a central light source. Each sphere consists of a grid formed by nine large intersecting rings; they divide the spherical surface into 48 similar spherical triangles. Maurits Cornelis Escher (Dutch. Maurits Cornelis June 17, 1898, Leeuwarden, Netherlands - March 27, 1972, Laren, Netherlands) - Dutch graphic artist.

Application of spherical triangle:

  1. Use of spherical triangles in 3D graphics
  2. In astronomy
  3. In geography. The spherical triangle theorem allows you to use the coordinates of two cities A and B to find the distance between them.
  4. In architecture
  5. Chair design by George Nelson
  6. In engraving

Spherical trigonometry

spherical triangles. On the surface of a ball, the shortest distance between two points is measured along the circumference of a great circle, that is, a circle whose plane passes through the center of the ball. Vertices of a spherical triangle are the intersection points of the three rays emerging from the center of the ball and the spherical surface. Parties a, b, c of a spherical triangle are called those angles between the rays that are smaller (if one of these angles is equal, then the spherical triangle degenerates into a semicircle of a great circle). Each side of the triangle corresponds to an arc of a large circle on the surface of the ball (see figure).

corners A, B, C spherical triangle opposite sides a, b, c respectively, are, by definition, smaller than , the angles between the arcs of great circles corresponding to the sides of the triangle, or the angles between the planes defined by these rays.

Spherical trigonometry deals with the study of the relationship between the sides and angles of spherical triangles (for example, on the surface of the Earth and on the celestial sphere). However, physicists and engineers in many problems prefer to use rotation transformations rather than spherical trigonometry.

Properties of spherical triangles. Each side and angle of a spherical triangle is, by definition, less than .

The geometry on the surface of the ball is non-Euclidean; in every spherical triangle the sum of the sides is between 0 and , the sum of the angles is between and . In every spherical triangle, the larger angle lies opposite the larger side. The sum of any two sides is greater than the third side, the sum of any two angles is less than plus the third angle.

Spherical triangle and basic formulas of spherical trigonometry

Many problems in astronomy related to the apparent positions and movements of celestial bodies are reduced to solving spherical triangles.

A spherical triangle is a figure ABC on the surface of a sphere, formed by arcs of three large circles (Fig. 15).

The angles of a spherical triangle are the dihedral angles between the planes of the great circles that form the sides of the spherical triangle. These angles are measured by the flat angles at the vertices of the triangle between the tangents to its sides.

Triangles are usually considered, the angles and sides of which are less than 180°. For such spherical triangles, the sum of the angles is always greater than 180° but less than 540°, and the sum of the sides is always less than 360°. The difference between the sum of the three angles of a spherical triangle and 180° is called the spherical excess σ, i.e.

σ = DA + DB + DC - 180°.

The area of ​​a spherical triangle s is

Where R is the radius of the sphere on the surface of which the triangle is formed.

A spherical triangle, therefore, differs in its properties from a flat one, and it is impossible to apply trigonometry formulas to it on a plane.

Take a spherical triangle ABC (Fig. 15), formed on a sphere of radius R and centered at point O.

From the vertex A we draw the tangents AD and AE to the sides b and c until they intersect with the extensions of the radii OS and 0B, which lie in the same plane with the corresponding tangent. Connecting the direct points of intersection of D and E, we obtain two flat oblique triangles ADE and ODE with a common side DE. Applying elementary geometry theorems to these triangles, we write:

DE 2 \u003d OD 2 + OE 2 - 2OD × OE × cos a,

DE 2 \u003d AD 2 + AE 2 - 2AD × AE × cos A.

By subtracting the second equation from the first, we get:

2OD × OE × cos a \u003d OD 2 - AD 2 + OE 2 - AE 2 + 2AD × AE × cos A. (1.31)

From right-angled flat triangles OAE and OAD it follows:

OD 2 -AD 2 =R 2 ;OE 2 -AE 2 =R 2 ;

AD = Rtg b ; AE = Rtg s;

Substituting these relations into formula (1.31) and making the corresponding reductions and transfers, we obtain

cos a \u003d cos b cos c + sin b sin c cos A, (1.32)

those. the cosine of a side of a spherical triangle is equal to the product of the cosines of its other two sides plus the product of the sines of the same sides and the cosine of the angle between them.

Formula (1.32) can be written for any side of the triangle. Let's write it, for example, for side b:

cos b = cos with cos a + sin with sin a cos B

and, substituting cos a into it from formula (1.32), we obtain

cos b = cos c (cos b cos c + sin b sin c cos A) + sin c sin a cos B.

Expanding the brackets and moving the first term of the right side to the left, we will have:

cos b (1 - cos 2 s) \u003d sin b sin with cos with cos A + sin c sin a cos B.

Replacing (1 - cos 2 s) with sin 2 s and reducing everything by sin c, we finally get

sin a cos B \u003d sinc cos b - cos c sin b cos A, (1.33)

those. the product of the sine of the side and the cosine of the included angle is equal to the product of the sine of the other side bounding the included angle by the cosine of the third side minus the product of the cosine of the side bounding the included angle by the sine of the third side and the cosine of the angle opposite the first side.

Formula (1.33) is called the formula of five elements. It can be written by analogy for the products of sin a cos C, sin b cos A, sin b cos C, sin with cos A and sin with cos B.

We now solve equality (1.32) with respect to cos A:

By squaring both sides of the last equality and subtracting them from 1, we get:

Opening the brackets and dividing both parts of this expression by sin 2 a, we get

The resulting expression is perfectly symmetrical with respect to a, b and c, and replacing A with B and b or A with C and a with c, we write

those. the sines of the sides of a spherical triangle are proportional to the sines of their opposite angles; or the ratio of the sine of a side of a spherical triangle to the sine of the opposite angle is a constant.

The three derived relations (1.32), (1.33), (1.34) between the sides and angles of a spherical triangle are the main ones; many other formulas of spherical trigonometry can be derived from them. We confine ourselves to deriving only one formula for a right-angled spherical triangle. Let A = 90°; then sin A \u003d 1, cos A \u003d 0, and from formula (1.33) we get

sin a cos B \u003d sin with cos b.

Dividing both parts of this equality by sin b and substituting, according to (1.34), we will have:

ctg B = sin c ctg b

those. the ratio of the tangent of one leg of a right-angled spherical triangle to the tangent of the opposite angle is equal to the sine of the other leg.

To represent information about an image on a Gaussian sphere in a computer, it makes sense to divide its surface into cells.

In this case, the area of ​​that part of the original surface, which is oriented inside the cone of directions determined by the partition cell, is associated with each cell. Such a discrete approximation of the extended spherical image is called the orientation histogram. Ideally, cells should meet the following requirements:

Have the same area;

Be the same shape

Be regularly spaced;

Have a rounded shape;

The partitioning should provide a sufficiently good angular resolution;

There must be rotations that take the partition into itself.

Elongated cells must be excluded, since they will correspond to information about surface areas, the orientation of which changes more than in the case of more rounded cells of the same area. At the same time, if the cells are arranged regularly, then their location in relation to their neighbors will be the same for all cells, and such configurations are highly desirable. Unfortunately, it is not possible to meet all of these requirements at the same time.

One of the possible partitions is formed by latitudinal belts, each of which is then subdivided by meridional stripes (Fig. 16.13). The resulting cells can be made almost equal in area if the number of such bands at high latitudes is reduced. One of the advantages of such a scheme is the simplicity of finding a cell to which it is necessary to assign a certain normal to the surface. However, such a method is too far from satisfying the requirements listed above. For example, there are no rotations with the help of which the constructed partition of the sphere is translated into itself (except for rotations about the axis connecting the poles).

More suitable partitions can be obtained by projecting onto the unit sphere regular polyhedra whose centers coincide with the center of the sphere. The faces of a regular polyhedron are regular polygons (and they are all the same). Therefore, the partition obtained by the projection of a regular polyhedron has the property that all cells have the same shape and area. In addition, the geometric arrangement of all cells with respect to their neighbors is the same. Unfortunately,

Rice. 16.13. The division of a sphere into elements by meridians and parallels. Unfortunately, such a partition has only a few of the properties required to store an orientation histogram.

Rice. 16.14. (see scan) Projecting a dodecahedron and an icosahedron onto a single sphere to obtain a partition into and cells.

only five regular bodies are known, from which one has to choose (tetrahedron, hexahedron, octahedron, dodecahedron and icosahedron). For a dodecahedron, the cells are quite rounded (Fig. 16.14, a). The dodecahedron, however, has only twelve faces. Even the icosahedron gives a very crude representation of orientation (Figure 16.14b). In addition, twenty of its cells are not very rounded.

We can go further and consider semi-regular polyhedra. Their faces are also regular polygons, but not necessarily the same. The areas of all faces are not equal. In some cases, it is possible to construct a new polyhedron that has the same topology of connections between faces as the original semiregular polyhedron, but whose face areas are equal. Wherein

Rice. 16.15. a - a truncated icosahedron, which is a semi-regular polyhedron with 32 faces; b - penta to decahedron, consisting of 60 triangular faces. Smaller partitions of the surface of the unit sphere can be based on such semiregular polyhedra.

Rice. 16.16. Ability to build geodetic networks based on any of the projections of regular or semi-regular polyhedra.

Each face is subdivided into triangular cells. The network shown here is based on the icosahedron and has 12 vertices, which are adjacent to 5 cells. Six cells converge at the remaining vertices.

the shape of some faces is no longer correct. An example of a partition based on a semi-regular polyhedron gives a soccer ball (Fig. 16.15, a). The truncated icosahedron, i.e., a body with 12 pentagonal and 20 hexagonal faces, is taken as the initial one. Unfortunately, there are only 13 semi-regular polyhedra (five truncated regular polyhedra, the cuboctahedron, icosidodecahedron, snub cube, snub icosidodecahedron, truncated cuboctahedron, rhombicuboctahedron, truncated icosododecahedron, and rhombicosidodecahedron). They do not lead to partitions small enough for our purposes.

If we still want to get a finer partition, then we can try to decompose the existing one into triangular elements. For example, if we break each of the pentagonal faces of the dodecahedron into five equal triangles, we get a pentadodecahedron with 60 faces (Fig. 16.15, b). Ohm is dual to the truncated icosahedron.

Proceeding in the same direction, each of the resulting triangles can be subdivided into four smaller triangles, in full accordance with the domed structures well known in geodesy (Fig. 16.16). By relaxing some of the above requirements, high resolution can be achieved. In fact, it is better to use dual constructions, since their faces are overwhelmingly (irregular) hexagons with 12 pentagons scattered between them (Fig. 16.15, b). Arbitrarily small partitions can be provided in this way.

To use this approach, it is necessary to be able to efficiently determine the element that corresponds to a given normal to the surface. In the case of partitions obtained on the basis of regular polyhedra, it is easy to calculate the cosines of the angles between a given unit vector and the vectors corresponding to the cell centers. (The latter correspond to the vertices of the dual

regular polyhedron.) Then the given vector is assigned to the cell whose center is closest. In the case of a partition similar to a geodetic network, it is possible to act in a hierarchical way. Such a partition is based on some regular polyhedron. The cell with the nearest center is found as described above. After that, we determine which of the triangles that subdivide it, the unit normal vector falls into. This process continues for the next four triangles subdividing the one found, and so on. In practice, table lookup methods can be used which, although not accurate, are very fast.

Let the solid angle filled by one cell on the sphere be (in the case of the icosahedron). The expected number of normals that fall inside such a cell for a convex object is

It is clear that the orientation histogram, i.e., the discrete approximation of the extended spherical image, can be computed locally. We simply count the number of normals that belong to each cell. At the same time, the Gaussian curvature is expressed in terms of the first and second partial derivatives of the function defining the surface. In practice, estimates of these derivatives turn out to be unreliable due to the presence of noise. Therefore, the fact that the extended spherical image can be calculated without calculating derivatives is very important.

The story of this demo is as follows: once a friend of mine made a planet map generator for his game and wanted the maps created in this way to be shown as a rotating sphere. However, at the same time, he did not want to use 3D graphics, but instead generated many frames with this same sphere rotated at different angles. The amount of memory used was ... shall we say, excessive, but the speed of frame generation (as well as the quality of their execution) suffered greatly. After a little thought, I managed to help him optimize this process, but in general I had a fair feeling that this was a task for OpenGL, and not for 2D graphics at all.

And so, one day, when I was tormented by insomnia, I decided to try to combine these two approaches: draw a rotating sphere (with a map of the planet stretched over it) through OpenGL, but at the same time leaving it flat.

And I must say that I succeeded. But first things first.

Process Mathematics

To begin with, let's define the actual task. For each point on the screen, we have two screen coordinates in the Cartesian coordinate system, and we need to find spherical coordinates for it (in fact, latitude and longitude), which, in fact, are the texture coordinates for the planet map.

So. The transition from a spherical coordinate system to a Cartesian one is given by a system of equations (taken from Wikipedia):

And the reverse transition - with such equations:

Coordinate Z we can easily get out X and Y, knowing the radius, and we can take the radius itself equal to one.
In the future, we will agree that we will slightly change the above equations by interchanging the concepts Y(for us it will be a screen vertical) and Z(this will be the depth of the scene).

Technical part

The implementation of the idea will require us to use a quad (I already talk about how to use it, so I won’t repeat it, especially since below is a link to the full source code of the project), as well as two textures: the actual map of the planet (I used the Earth texture of 2048x1024 ) and texture coordinate maps. The code for generating the second texture neatly repeats the mathematics of converting from Cartesian to spherical coordinates:

int texSize = 1024; double r = texSize * 0.5; int pixels = new int; for (int row = 0, idx = 0; row< texSize; row++) { double y = (r - row) / r; double sin_theta = Math.sqrt(1 - y*y); double theta = Math.acos(y); long v = Math.round(255 * theta / Math.PI); for (int col = 0; col < texSize; col++) { double x = (r - col) / r; long u = 0, a = 0; if (x >= -sin_theta && x<= sin_theta) { double z = Math.sqrt(1 - y*y - x*x); double phi = Math.atan2(z, x); u = Math.round(255 * phi / (2 * Math.PI)); a = Math.round(255 * z); } pixels = (int) ((a << 24) + (v << 8) + u); } } GLES20.glGenTextures(1, genbuf, 0); offsetTex = genbuf; if (offsetTex != 0) { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, offsetTex); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_NONE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_NONE); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texSize, texSize, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels)); }
Note that the coordinates X and Y are transferred from the range to the range [-1..1], and the texture coordinates U and V are converted from radians to the range , after which they are written to the red and green components of the 32-bit texture, respectively. The alpha channel is used to store "depth" (coordinates Z), while blue remains unused for now. Disabling bilinear filtering is also not accidental: at this stage it does not give any effect (neighboring points in any case have the same values, with rather sharp jumps), and in what I am going to show next, it will be harmful. But more on that below.

Both textures are fed to the input of a simple pixel shader (hereinafter, the pictures are clickable):

Private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "varying vec4 TexCoord0;\n" + "void main() (\n" + " vec4 vTex = texture2D(uTexture0, TexCoord0.xy);\n" + " vec3 vCol = texture2D(uTexture1, vTex.xy).rgb;\n" + " gl_FragColor = vec4(vCol, (vTex.w >
I don’t provide the scene rendering code, because everything is rather trivial in it (and, again, you can see it in the full source), and the shader itself is quite primitive. The most curious thing about it, perhaps, is that the alpha channel is only checked for positivity so far, while it could be used for a lighting effect.

It turned out quite well, but somehow flat, plus I would like to add the actual rotation of the planet around its axis.

We include one more parameter in the shader (we will change it depending on the time in the range), plus we add “depth” (multiplying the color by the value from the alpha channel):

Private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "uniform float uOffset;\n" + "varying vec4 TexCoord0;\n" + "void main() (\n" + " vec4 vTex = texture2D(uTexture0, TexCoord0.xy);\n" + " vTex.x += uOffset;\n" + " vec3 vCol = texture2D(uTexture1, vTex.xy ).rgb;\n" + " gl_FragColor = vec4(vCol * vTex.w, (vTex.w > 0.0 ? 1.0: 0.0));\n" + ")\n";
Well, there are no complaints about the sphere itself, but the picture looks somehow ... eight-bit, or something. And no wonder: we recorded texture coordinates in a range (the maximum available to us in ordinary color components), which means that our texture can have no more than 256 points in height (and 512 in width, considering rotation). Not enough, you need at least 10-bit precision.

Increasing the resolution

I immediately warn you: the code described here may work crookedly on any devices, although I managed to achieve normal rendering on all devices that I could hold in my hands. In any case, what is described here is a common hack.

So, we have used two of the three color components so far, i.e. 16 bits out of 24. Well, let's pack the data so that each texture coordinate has a size of 12 bits, which will allow us to work with textures up to 4096 pixels in height! To do this, we will change literally three lines in the program:

Long v = Math.round(4095 * theta / Math.PI); ...u = Math.round(4095 * phi / (2 * Math.PI)); ... pixels = (int) ((a<< 24) + (v << 12) + ((u & 15) << 8) + (u >> 4)); ...
and write a new shader that takes into account the 12-bit addressing scheme (this is the place where bilinear filtering must be disabled!):

private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "uniform float uOffset;\n" + "varying vec4 TexCoord0;\n" + "void main() (\n" + " vec4 vTex = texture2D(uTexture0, TexCoord0.xy);\n" + " vec3 vOff = vTex.xyz * 255.0 + vec3(0.5, 0.5, 0.5);\n" + " float hiY = floor(vOff.y / 16.0);\n" + " float loY = vOff.y - 16.0 * hiY;\n" + " vec2 vCoord = vec2(\n" + " (vOff.x * 16.0 + loY) / 4095.0 + uOffset,\n" + " (vOff.z * 16.0 + hiY) / 4095.0);\n" + " vec3 vCol = texture2D(uTexture1, vCoord).rgb;\n" + " gl_FragColor = vec4(vCol * vTex.w, (vTex.w > 0.0 ? 1.0: 0.0));\n" + ")\n";
Well, this is a completely different matter! With minor changes (adding pinch zoom and finger rotation), I showed this program to my friends and colleagues, and at the same time asked how many triangles they thought were in this scene. The results varied, and the question itself aroused suspicion of the presence of a catch (in this case, the respondents joked “one”, which was not far from the truth), but the correct answer was consistently surprising. And everyone, as one, asked: why can a sphere be rotated around one axis, but not tilted? .. Hmm.

Incline

But the fact is that the slope in this scheme is much more difficult to implement. In fact, the task is not unsolvable, and I even coped with it, but not without nuances.

In essence, the task comes down to taking the shifted coordinate V, while the coordinate U does not change: this is because we add rotation around the axis X. The plan is as follows: we transform the texture coordinates into screen coordinates (in the range [-1..1]), apply the rotation matrix around the horizontal axis to them (to do this, we write in a new constant in advance uTilt sine and cosine of the angle of inclination), and then we use the new coordinate Y to sample in our template texture. "Rotated" coordinate Z it will also come in handy for us, with its help we will mirror the longitude for the back side of the ball). Screen coordinate Z you will have to calculate explicitly in order not to make two texture selections from one texture, at the same time this will increase its accuracy.

private final String quadFS = "precision mediump float;\n" + "uniform sampler2D uTexture0;\n" + "uniform sampler2D uTexture1;\n" + "uniform float uOffset;\n" + "uniform vec2 uTilt;\n" + "varying vec4 TexCoord0;\n" + "void main() (\n" + " float sx = 2.0 * TexCoord0.x - 1.0;\n" + " float sy = 2.0 * TexCoord0.y - 1.0;\n" + " float z2 = 1.0 - sx * sx - sy * sy;\n" + " if (z2 > 0.0) (;\n" + " float sz = sqrt(z2);\n" + " float y = ( sy * uTilt.y - sz * uTilt.x + 1.0) * 0.5;\n" + " float z = (sy * uTilt.x + sz * uTilt.y);\n" + " vec4 vTex = texture2D(uTexture0 , vec2(TexCoord0.x, y));\n" + " vec3 vOff = vTex.xyz * 255.0 + vec3(0.5, 0.5, 0.5);\n" + " float hiY = floor(vOff.y / 16.0) ;\n" + " float loY = vOff.y - 16.0 * hiY;\n" + " vec2 vCoord = vec2(\n" + " (vOff.x * 16.0 + loY) / 4095.0,\n" + " ( vOff.z * 16.0 + hiY) / 4095.0);\n" + " if (z< 0.0) { vCoord.x = 1.0 - vCoord.x; }\n" + " vCoord.x += uOffset;\n" + " vec3 vCol = texture2D(uTexture1, vCoord).rgb;\n" + " gl_FragColor = vec4(vCol * sz, 1.0);\n" + " } else {\n" + " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "}\n";
Hooray, the slope worked! That's just a strange noise at the border of the hemispheres a little embarrassing. Obviously, the problem lies in the insufficient addressing accuracy at the boundary points (the points on the circle itself correspond to a too large range of coordinates, one texel spreads over an interval of a rather noticeable length). In the end, I managed to defeat this by using two generated textures instead of one.

As a result, you can zoom in and rotate the ball in much the same way as in Google Earth. With the difference that there are only two triangles.

And finally, the promise. The source code for the project is available at