gmlscripts

polygon_to_triangles

Jun 26th, 2014
374
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /// polygon_to_triangles(polygon)
  2. //
  3. //  Returns a list of triangles created from a given 2D polygon.
  4. //
  5. //      polygon     ds_list of an ordered series of coordinate
  6. //                  pairs defining the shape of a polygon
  7. //
  8. //  The polygon vertices are given and returned in traditional
  9. //  counter-clockwise order. Polygons are closed figures with edges
  10. //  spanning consecutive vertices and from the last vertex to the
  11. //  first. Polygons must be simple, which means they cannot have
  12. //  edges that cross one another. The number of triangles created
  13. //  is (n-2), where n is the number of vertices in the polygon.
  14. //
  15. //  eg. in:  square polygon = { 100,100,  100,200,  200,200,  200,100 }
  16. //
  17. //      out: two triangles = { 100,100,  100,200,  200,100,  
  18. //                             100,200,  200,200,  200,100 }
  19. //
  20. //  Depends on lines_intersect() and point_in_triangle().
  21. //
  22. /// GMLscripts.com/license
  23. {
  24.     var polygon, polygonSize, triangles, points, polyX, polyY, good;
  25.     var i, j, n, p, A, B, C, x0, y0, x1, y1, x2, y2, x3, y3, x4, y4;
  26.     polygon = argument0;
  27.     polygonSize = ds_list_size(polygon) div 2;
  28.     triangles = ds_list_create();
  29.     points = ds_list_create();
  30.     polyX = ds_list_create();
  31.     polyY = ds_list_create();
  32.    
  33.     i = 0;
  34.     repeat (polygonSize)
  35.     {
  36.         ds_list_add(polyX, ds_list_find_value(polygon, i));
  37.         ds_list_add(polyY, ds_list_find_value(polygon, i+1));
  38.         i += 2;
  39.     }
  40.    
  41.     // 1. For (n - 3) vertices
  42.     n = polygonSize;
  43.     for (n = polygonSize; n > 3; n -= 1)
  44.     {
  45.         //  a. Select first point (random)    
  46.         ds_list_clear(points);
  47.         for (p = 0; p < n; p += 1) ds_list_add(points, p);
  48.         repeat (p)
  49.         {
  50.             i = floor(random(ds_list_size(points)));
  51.             A = ds_list_find_value(points, i);
  52.             ds_list_delete(points, i);
  53.            
  54.             //  b. Pick the next two points
  55.             B = (A + 1) mod n;
  56.             C = (A + 2) mod n;
  57.            
  58.             //  c. Make a triangle with the selected points
  59.             x0 = ds_list_find_value(polyX, A);
  60.             y0 = ds_list_find_value(polyY, A);
  61.             x1 = ds_list_find_value(polyX, B);
  62.             y1 = ds_list_find_value(polyY, B);
  63.             x2 = ds_list_find_value(polyX, C);
  64.             y2 = ds_list_find_value(polyY, C);
  65.            
  66.             //  d. If triangle is counter-clockwise...
  67.             if ((x1 - x0) * (y2 - y0) + (y0 - y1) * (x2 - x0) < 0)
  68.             {
  69.                 good = true;
  70.                 //  ...and if triangle has no vertices within it...
  71.                 for (i = 0; i < n; i += 1)
  72.                 {
  73.                     if ((i != A) && (i != B) && (i != C))
  74.                     {
  75.                         x3 = ds_list_find_value(polyX, i);
  76.                         y3 = ds_list_find_value(polyY, i);
  77.                         if (point_in_triangle(x3, y3, x0, y0, x1, y1, x2, y2))
  78.                         {
  79.                             good = false;
  80.                             break;
  81.                         }
  82.                         //  ...and if the new edge has no other edges crossing it...
  83.                         j = (i + 1) mod n;
  84.                         if ((j != A) && (j != B) && (j != C))
  85.                         {
  86.                             x4 = ds_list_find_value(polyX, j);
  87.                             y4 = ds_list_find_value(polyY, j);
  88.  
  89.                             if (lines_intersect(x0, y0, x2, y2, x3, y3, x4, y4, true) != 0)
  90.                             {
  91.                                 good = false;
  92.                                 break;
  93.                             }
  94.                         }
  95.                     }
  96.                 }
  97.                
  98.                 //  e.  ...then add the triangle to list and remove the unshared vertex
  99.                 if (good)
  100.                 {
  101.                     ds_list_add(triangles, x0);
  102.                     ds_list_add(triangles, y0);
  103.                     ds_list_add(triangles, x1);
  104.                     ds_list_add(triangles, y1);
  105.                     ds_list_add(triangles, x2);
  106.                     ds_list_add(triangles, y2);
  107.                     ds_list_delete(polyX, B);
  108.                     ds_list_delete(polyY, B);
  109.                     break;
  110.                 }
  111.             }
  112.         }
  113.     }
  114.    
  115.     //  2. There are only three vertices left, so add the final triangle to the list
  116.     ds_list_add(triangles, ds_list_find_value(polyX, 0));
  117.     ds_list_add(triangles, ds_list_find_value(polyY, 0));
  118.     ds_list_add(triangles, ds_list_find_value(polyX, 1));
  119.     ds_list_add(triangles, ds_list_find_value(polyY, 1));
  120.     ds_list_add(triangles, ds_list_find_value(polyX, 2));
  121.     ds_list_add(triangles, ds_list_find_value(polyY, 2));
  122.    
  123.     //  3. Clean up
  124.     ds_list_destroy(polyX);
  125.     ds_list_destroy(polyY);
  126.     ds_list_destroy(points);
  127.    
  128.     return triangles;
  129. }
Advertisement
Add Comment
Please, Sign In to add comment