diff --git a/xy/regular_polygon.go b/xy/regular_polygon.go new file mode 100644 index 00000000..55f6b738 --- /dev/null +++ b/xy/regular_polygon.go @@ -0,0 +1,22 @@ +package xy + +import ( + "math" + + "github.com/twpayne/go-geom" +) + +// RegularPolygon returns an n-sided regular polygon centered at center with radius r. +func RegularPolygon(n int, center *geom.Point, r float64) *geom.Polygon { + pointFlatCoords := center.FlatCoords() + stride := center.Stride() + flatCoords := make([]float64, (n+1)*stride) + for i := 0; i < n; i++ { + theta := 2 * math.Pi * float64(i) / float64(n) + flatCoords[i*stride] = pointFlatCoords[0] + r*math.Cos(theta) + flatCoords[i*stride+1] = pointFlatCoords[1] + r*math.Sin(theta) + copy(flatCoords[i*stride+2:(i+1)*stride], pointFlatCoords[2:stride]) + } + copy(flatCoords[n*stride:(n+1)*stride], flatCoords[:stride]) + return geom.NewPolygonFlat(center.Layout(), flatCoords, []int{(n + 1) * stride}) +} diff --git a/xy/regular_polygon_test.go b/xy/regular_polygon_test.go new file mode 100644 index 00000000..db78d6de --- /dev/null +++ b/xy/regular_polygon_test.go @@ -0,0 +1,31 @@ +package xy_test + +import ( + "testing" + + "github.com/alecthomas/assert/v2" + + "github.com/twpayne/go-geom" + "github.com/twpayne/go-geom/xy" +) + +func TestRegularPolygon(t *testing.T) { + for _, tc := range []struct { + n int + center *geom.Point + r float64 + expectedCoords [][]geom.Coord + }{ + { + n: 4, + center: geom.NewPoint(geom.XY).MustSetCoords([]float64{1, 2}), + r: 1, + expectedCoords: [][]geom.Coord{{{2, 2}, {1, 3}, {0, 2}, {1, 1}, {2, 2}}}, + }, + } { + t.Run("", func(t *testing.T) { + actual := xy.RegularPolygon(tc.n, tc.center, tc.r) + assert.Equal(t, tc.expectedCoords, actual.Coords()) + }) + } +}