This is the third article in this series. The first two articles introduce the principle of image distortion in HTML5 and the detailed usage of the drawtriangles function. The connection is as follows:
Graphic distortion and Its Application in HTML5 advanced programming I (Principles)
Http://blog.csdn.net/lufy_legend/article/details/8084367
Graphic distortion and Its Application in HTML5 advanced programming II (Application)
Http://blog.csdn.net/lufy_legend/article/details/8113566
Let's take a look at the extensions of the drawtriangles function.Use the drawtriangles function to implementRotate3D Earth, the effect is as follows
Because the drawtriangles function of lufylegend1.5.0 has a bug, I have quietly updated lufylegend1.5.1. You can download it from the official website:
Http://lufylegend.com/lufylegend
In fact, to draw a 3D sphere effect, first draw a plane, then divide the plane into small triangles, and then splice these small triangles into a sphere.
Now, create a blank lbitmapdata object and divide it into N small triangles. For more information, see the following code:
earthBitmapData = new LBitmapData("#ffffff", 0, 0, 500, 300);var i, j;vertices = new Array();for(i=0;i<=cols;i++){for(j=0;j<=rows;j++){vertices.push(i*15,j*15);}}indices = new Array();for (i = 0; i < cols; i++) {for (j = 0; j < rows; j++) {indices.push(i * (rows + 1) + j, (i + 1) * (rows + 1) + j, i * (rows + 1) + j + 1);indices.push((i + 1) * (rows + 1) + j, i * (rows + 1) + j + 1, (i + 1) * (rows + 1) + j + 1);}}uvtData = new Array();for (i = 0; i <= cols; i++) {for (j = 0; j <= rows; j++) {uvtData.push(i / cols, j / rows);}}
Next, use the drawtriangles function to draw the lbitmapdata object to the screen.
backLayer = new LSprite();addChild(backLayer);backLayer.graphics.clear();backLayer.graphics.beginBitmapFill(earthBitmapData);backLayer.graphics.drawTriangles(vertices, indices, uvtData, 2);
The result is as follows.
To program a circle in this plane, you need to calculate the coordinates of each small triangle in the graph. First, let's see how the Y coordinate is calculated. Then, let's look at the figure below, which is the vertical section of a ball.
Using trigonometric functions, calculate the Y coordinate in the graph, and the radius of the horizontal plane circle of the ball where the Y coordinate is located r1
var a = Math.sin(angle);if((90-180*j/rows)%90==0 && (90-180*j/rows)%180!=0)a=(90-180*j/rows)>0?1:-1;var y = -r*a;var sa = Math.cos(angle);var r1 = Math.abs(r*sa);
Therefore, we first bring the calculated Y coordinates into the vertices array.
for(i=0;i<=cols;i++){for(j=0;j<=rows;j++){var angle = (90-180*j/rows)*Math.PI/180;var a = Math.sin(angle);if((90-180*j/rows)%90==0 && (90-180*j/rows)%180!=0)a=(90-180*j/rows)>0?1:-1;if((90-180*j/rows)%180==0)a=0;var sy = -r*a;vertices.push(i*15,sy);}}
Because the coordinates of X have not been calculated, a special image is obtained as follows:
Next, let's see how to calculate the coordinates of X. First, take out the plane section with the radius of R1, as shown in figure
Use trigonometric functions to calculate X coordinates in a graph
var b = Math.cos(angle*Math.PI/180);var x = r1*b;
At this time, if we only bring the calculated X coordinates into the vertices array
for(i=0;i<=cols;i++){for(j=0;j<=rows;j++){var sa = Math.cos(angle);if((90-180*j/rows)%180==0)sa=1;var sr = Math.abs(r*sa);var angle2 = 360*(i+1)/cols;var b = Math.cos(angle2*Math.PI/180);if(angle2%360==0)b=1;else if(angle2%180==0)b=-1;var sx = sr*b;vertices.push(sx,j*15);}}
The Y coordinate is not calculated, so an interesting image is obtained, as shown below:
If the calculated x and y coordinates are included in the vertices array
for(i=0;i<=cols;i++){for(j=0;j<=rows;j++){var angle = (90-180*j/rows)*Math.PI/180;var a = Math.sin(angle);if((90-180*j/rows)%90==0 && (90-180*j/rows)%180!=0)a=(90-180*j/rows)>0?1:-1;if((90-180*j/rows)%180==0)a=0;var sy = -r*a;var sa = Math.cos(angle);if((90-180*j/rows)%180==0)sa=1;var sr = Math.abs(r*sa);var angle2 = 360*(i+1)/cols;var b = Math.cos(angle2*Math.PI/180);if(angle2%360==0)b=1;else if(angle2%180==0)b=-1;var sx = sr*b;vertices.push(sx, sy);}}
Obtain a complete sphere image, as shown below:
Next, it's easy to replace the blank image with a map of the earth. The Code is as follows:
earthBitmapData = new LBitmapData(imglist["earth"]);
Run the code again to get the following 3D image.
Next, let the earth turn up. According to the content introduced in the previous article, the elements in the uvtdata array of the drawtriangles function are the relative positions of each small triangle in the original image, they determine the starting position of the image. If a group of positions, such as 0123, are changed to 1230 and then to 2301, the positions are constantly changed, so visually, the rotation has actually been realized. In the code, you only need to move the split array according to each column, every time we move the two groups of triangles in the first column to the last column, the two groups of triangles in the second column will become the first column, so that the constant transformation will make one earth rotate.
for (i = 0; i <= rows; i++) {uvtData.push(uvtData.shift());uvtData.push(uvtData.shift());}
If you want to change the size of the Earth, it will be simpler. You can change the scalex and scaley attributes of the lsprite object to change the size of the object. You can click the following link, to test its effect.
Http://lufy.netne.net/lufylegend-js/3dearth/index.html
Note:
Again, the content described in this article requires the support of version 1.5.1 or later of the HTML5 Open-Source engine lufylegend1.5.1. The lufylegend1.5.1 release address is as follows:
Http://lufylegend.com/lufylegend
Reprinted Please note: transferred from lufy_legend's blog
Continue to follow my blog
Http://blog.csdn.net/lufy_legend