This algorithm decomposes a general polygon into simple polygons and uses the “ear-clipping” algorithm to triangulate it. Polygons with holes are supported.

triangulate(x, y = NULL, z = NULL, random = TRUE, plot = FALSE, partial = NA)

Arguments

x, y, z

Coordinates of a two-dimensional polygon in a format supported by xyz.coords. See Details for how z is handled.

random

Whether to use a random or deterministic triangulation.

plot

Whether to plot the triangulation; mainly for debugging purposes.

partial

If the triangulation fails, should partial results be returned?

Details

Normally triangulate looks only at the x and y coordinates. However, if one of those is constant, it is replaced with the z coordinate if present.

The algorithm works as follows. First, it breaks the polygon into pieces separated by NA values in x or y. Each of these pieces should be a simple, non-self-intersecting polygon, separate from the other pieces. (Though some minor exceptions to this rule may work, none are guaranteed). The nesting of these pieces is determined.

The “outer” polygon(s) are then merged with the polygons that they immediately contain, and each of these pieces is triangulated using the ear-clipping algorithm.

Finally, all the triangulated pieces are put together into one result.

Value

A three-by-n array giving the indices of the vertices of each triangle. (No vertices are added; only the original vertices are used in the triangulation.) The array has an integer vector attribute "nextvert"with one entry per vertex, giving the index of the next vertex to proceed counter-clockwise around outer polygon boundaries, clockwise around inner boundaries.

References

See the Wikipedia article “polygon triangulation” for a description of the ear-clipping algorithm.

Author

Duncan Murdoch

Note

Not all inputs will succeed, even when a triangulation is possible. Generally using random = TRUE will find a successful triangulation if one exists, but it may occasionally take more than one try.

See also

extrude3d for a solid extrusion of a polygon, polygon3d for a flat display; both use triangulate.

Examples

theta <- seq(0, 2*pi, len = 25)[-25]
theta <- c(theta, NA, theta, NA, theta, NA, theta, NA, theta)
r <- c(rep(1.5, 24), NA, rep(0.5, 24), NA, rep(0.5, 24), NA, rep(0.3, 24), NA, rep(0.1, 24))
dx <- c(rep(0, 24), NA, rep(0.6, 24), NA, rep(-0.6, 24), NA, rep(-0.6, 24), NA, rep(-0.6, 24))
x <- r*cos(theta) + dx
y <- r*sin(theta)
plot(x, y, type = "n")
polygon(x, y)
triangulate(x, y, plot = TRUE)

#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#> [1,]   73   72   71   71   39   38   70   37   36    36    70    35    34    33
#> [2,]   72   71   40   70   38   37   41   36    5    35    15    34    33    32
#> [3,]   39   39   39   40   73   73   40   73   73     5    41     5     5     5
#>      [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
#> [1,]    32    31    70    69    30    29    68    67    66    65    64    28
#> [2,]    31    30    69    68    29    28    67    66    65    64    63    24
#> [3,]     5     5    15    15     5     5    15    15    15    15    15     5
#>      [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38]
#> [1,]    28    63    27    26    49    48    62    62    61    47     5    60
#> [2,]    27    62    26    49    48    47    11    61    60    46    74    59
#> [3,]    24    15    24    24    24    24    15    11    11    24    73    11
#>      [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50]
#> [1,]    59     5    58    46     5    45    45    44     5    57    19     5
#> [2,]    58    51    57    45    52    19    44    15    53     6    21    54
#> [3,]    11    74    11    24    51    24    19    19    52    11    24    53
#>      [,51] [,52] [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61] [,62]
#> [1,]    15    21     5    57    56    11    15    24     1    15    19     2
#> [2,]    18    22    55    56    55    13    42     1     2    16    20     3
#> [3,]    19    24    54     6     6    15    41     5     5    18    21     5
#>      [,63] [,64] [,65] [,66] [,67] [,68] [,69] [,70] [,71] [,72] [,73] [,74]
#> [1,]     6     5     9    16     6    15    22     3    13    44     6    11
#> [2,]     9     6    10    17     8    43    23     4    14    43     7    12
#> [3,]    11    55    11    18     9    42    24     5    15    15     8    13
#>      [,75] [,76] [,77] [,78] [,79] [,80] [,81] [,82] [,83] [,84] [,85] [,86]
#> [1,]   122    95   121    95    95   120    77    77   119    77   119   118
#> [2,]   121   123   120   124    77   119   101   102    89   103   118   117
#> [3,]    95   122    95   123   124    95   124   101    95   102    89    89
#>      [,87] [,88] [,89] [,90] [,91] [,92] [,93] [,94] [,95] [,96] [,97] [,98]
#> [1,]   117    77   116    77    77   115   114    77   113    77    80   113
#> [2,]   116   104   115   105   106   114   113   107    83    80   108   112
#> [3,]    89   103    89   104   105    89    89   106    89   107   107    83
#>      [,99] [,100] [,101] [,102] [,103] [,104] [,105] [,106] [,107] [,108]
#> [1,]    80    112     83     95     83     77    111     95     78     89
#> [2,]   109    111     88     76     84     78    110     97     79     90
#> [3,]   108     83     89     77     88     80     83     76     80     95
#>      [,109] [,110] [,111] [,112] [,113] [,114] [,115] [,116] [,117] [,118]
#> [1,]    110     90     92     84     84    110     80     95     84     80
#> [2,]     82     92     94     87     86    109     82     96     85     81
#> [3,]     83     95     95     88     87     82    109     97     86     82
#>      [,119] [,120] [,121] [,122]
#> [1,]     90     92     97     98
#> [2,]     91     93     98     99
#> [3,]     92     94     76     76
#> attr(,"nextvert")
#>   [1]   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
#>  [19]  20  21  22  23  24   1  NA  49  26  27  28  29  30  31  32  33  34  35
#>  [37]  36  37  38  39  40  41  42  43  44  45  46  47  48  NA  74  51  52  53
#>  [55]  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71
#>  [73]  72  73  NA  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91
#>  [91]  92  93  94  95  96  97  98  99  76  NA 124 101 102 103 104 105 106 107
#> [109] 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
open3d()
polygon3d(x, y, x - y, col = "red")