Using canvas to achieve a picture triangulation (low POLY) effect

Source: Internet
Author: User

  Before inadvertently saw Ovilia with Threejs did a low POLY, that is, the image of the triangular effect of the plane, feel very stunning, and then took a little time to try.

I did not use the Threejs, so I directly use the canvas 2d drawing API to do, because it feels like this effect is not threejs.

Directly on the demo first: http://whxaxes.github.io/canvas-test/src/Funny-demo/lowpoly/index.html (can also be seen on the mobile side, but because the computational capacity is relatively large, Mobile devices can take more time to calculate than PCs. )

To do this, it is necessary to triangulate the images and to detect the edges of the images. These two, the first used Delaunay triangulation algorithm, the second use of the Sobel edge detection algorithm. It sounds like a big steal. Two algorithms have a corresponding open source component that can be used directly:the Ironwallaby Delaunay component and the Sobel component of the Miguel Mota.

These two algorithms Sobel fortunately a bit, Delaunay is a bit complicated, can be studied later. But for now, these components can be used only to make an effect.

The two most important components are there, and the rest is simple:

First draw the picture onto the canvas:

Canvas.width = (Img.width > 800)? img.height * canvas.width/img.width;  0, 0, canvas.width, canvas.height);

  Then get to the canvas's imgdata, and then return the new Imgdata by Sobel calculation

var imgdata = ctx.getimagedata (0, 0, Canvas.width, canvas.height); var newimgdata = Sobel (Imgdata);

If we put the newimgdata on the canvas, we will find that the color image becomes such a grayscale image:

  

  After the picture is processed, the imgdata is traversed, and the coordinate points of the color value greater than 40 (that is, the grayscale is more than RGB (40,40,40)) are recorded. Because we want to randomly select some of the coordinate points at the edge, so the collected coordinates are scrambled, and then added some random coordinates and four corner coordinate values. So that we can get to the coordinate point we need.

varCollectors = [];varindex;//collect edge points with color values greater than 40 for(varx=0;x){    for(vary=0;y) {Index= ~ ~ (y*imgdata.width + x); if(Newimgdata.data[index] > 40) {Collectors.push ([x, y]); }   }}//random arrangement of collected pointsCollectors.sort (function(){returnMath.random ()-math.random ()});//add some random points for(vari=0;i<500;i++) {Particles.push ([Math.random () *canvas.width, Math.random () *canvas.height]);}//Add edge pointsparticles = Particles.concat (Collectors.slice (0,~~ (COLLECTORS.LENGTH/50)));//add four vertex coordinatesparticles = Particles.concat ([[0,0], [0,canvas.height], [canvas.width,0], [canvas.width,canvas.height]]);

  Once the coordinate point is obtained, it can be computed by the Delaunay component, get the array of triangular coordinates in the order of the sequence, and connect the points in these arrays so that the effect can occur:

  

Of course, the effect we want is not the line, but the color of all the triangles to fill, that is, to get the three coordinates of the triangle, and then calculate the coordinates of the center point, and then according to the center point coordinates in the imgdata to obtain the corresponding RGB color values, and then fill the Triangle area can be:

//triangular coordinates obtained using Delaunay triangulationvarTriangles =delaunay.triangulate (particles);varX1,x2,x3,y1,y2,y3,cx,cy; for(varI=0;i < Triangles.length; I+=3) {x1= Particles[triangles[i]][0]; X2= Particles[triangles[i+1]][0]; X3= Particles[triangles[i+2]][0]; Y1= Particles[triangles[i]][1]; Y2= Particles[triangles[i+1]][1]; Y3= Particles[triangles[i+2]][1];//Get Triangle Center Point coordinatesCX = ~ ~ ((x1 + x2 + x3)/3); Cy= ~ ~ ((y1 + y2 + y3)/3);//gets the color value of the center point coordinateIndex = (cy*imgdata.width + cx); varColor_r =Imgdata.data[index]; varColor_g = imgdata.data[index+1]; varColor_b = imgdata.data[index+2];//Draw TrianglesCtx.save ();    Ctx.beginpath ();    Ctx.moveto (x1, y1);    Ctx.lineto (x2, y2);    Ctx.lineto (x3, y3);    Ctx.closepath (); Ctx.fillstyle= "Rgba (" +color_r+ "," +color_g+ "," +color_b+ ", 1)";    Ctx.fill (); Ctx.restore ();}

  It is important to note that the obtained center point coordinates must be rounded to get the correct color parameters, if you want to not take the whole, but in the acquisition of RGB index and then take the whole, get the color value is wrong. Because that pixel is not the center pixel we want to get.

The color is also obtained after the simple connection, then the filling operation, the final effect is:

  

  

  Although there is no designer hand-painted look good, but also a lot of convenience, do to play or very interesting.

Source address, interested can a look at Kazakhstan:

Https://github.com/whxaxes/canvas-test/tree/gh-pages/src/Funny-demo/lowpoly

Using canvas to achieve a picture triangulation (low POLY) effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.