View difference between Paste ID: ewSquvP4 and asCE3NcA
SHOW: | | - or go back to the newest paste.
1
///shape_to_triangles(shape)
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
    p0,p1,p2,p3,p4;
27
    polygon = argument0;
28
    polygonSize = ds_list_size(polygon);
29
    triangles = ds_list_create();
30
    points = ds_list_create();
31
    polyP = ds_list_create();
32
33
    i = 0;
34
    repeat (polygonSize) 
35
    {
36
        ds_list_add(polyP, ds_list_find_value(polygon, i));
37
        i += 1;
38
    }
39
40
    // 1. For (n - 3) vertices
41
    n = polygonSize;
42
    for (n = polygonSize; n > 3; n -= 1) 
43
    {
44
        //  a. Select first point (random)    
45
        ds_list_clear(points);
46
        for (p = 0; p < n; p += 1) ds_list_add(points, p);
47
        repeat (p) 
48
        {
49
            i = floor(random(ds_list_size(points)));
50
            A = ds_list_find_value(points, i);
51
            ds_list_delete(points, i);
52
53
            //  b. Pick the next two points
54
            B = (A + 1) mod n;
55
            C = (A + 2) mod n;
56
57
            //  c. Make a triangle with the selected points
58
            p0 = ds_list_find_value(polyP, A);
59
            p1 = ds_list_find_value(polyP, B);
60
            p2 = ds_list_find_value(polyP, C);
61
            
62
            x0 = point_x(p0); y0 = point_y(p0);
63
            x1 = point_x(p1); y1 = point_y(p1);
64
            x2 = point_x(p2); y2 = point_y(p2);
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
                        p3 = ds_list_find_value(polyP,i);
76
                        x3 = point_x(p3);
77
                        y3 = point_y(p3);
78
                        if (point_in_triangle(x3, y3, x0, y0, x1, y1, x2, y2)) 
79
                        { 
80
                            good = false; 
81
                            break; 
82
                        }
83
                        //  ...and if the new edge has no other edges crossing it...
84
                        j = (i + 1) mod n;
85
                        if ((j != A) && (j != B) && (j != C)) 
86
                        {
87
                            p4 = ds_list_find_value(polyP,j);
88
                            x4 = point_x(p4);
89
                            y4 = point_y(p4);
90
91
                            if (lines_intersect(x0, y0, x2, y2, x3, y3, x4, y4, true) != 0)
92
                            { 
93
                                good = false; 
94
                                break; 
95
                            }
96
                        }
97
                    }
98
                }
99
100
                //  e.  ...then add the triangle to list and remove the unshared vertex
101
                if (good) 
102
                {
103
                    ds_list_add(triangles, p0);
104
                    ds_list_add(triangles, p1);
105
                    ds_list_add(triangles, p2);
106
                    ds_list_delete(polyP, B);
107
                    break;
108
                }
109
            }
110
        }
111
    }
112
113
    //  2. There are only three vertices left, so add the final triangle to the list
114
    ds_list_add(triangles, ds_list_find_value(polyP, 0));
115
    ds_list_add(triangles, ds_list_find_value(polyP, 1));
116
    ds_list_add(triangles, ds_list_find_value(polyP, 2));
117
118
    //  3. Clean up
119
    ds_list_destroy(polyP);
120
    ds_list_destroy(points);
121
122
    return triangles;
123
}