func MakeBezierCurve2D(numPoints int, cPoints []Vec2) (line []Vec2) {
	line = make([]Vec2, numPoints)
	if numPoints == 0 {
		return
	} else if numPoints == 1 {
		line[0] = cPoints[0]
		return
	} else if numPoints == 2 {
		line[0] = cPoints[0]
		line[1] = cPoints[len(cPoints)-1]
		return
	}
	line[0] = cPoints[0]
	for i := 1; i < numPoints-1; i++ {
		line[i] = BezierCurve2D(Clamp(float32(i)/float32(numPoints-1), 0.0, 1.0), cPoints)
	}
	line[numPoints-1] = cPoints[len(cPoints)-1]
	return
}
MakeBezierCurve2D generates a bezier curve with controlPoints cPoints. The
numPoints argument determines how many "samples" it makes along the line. For
instance, a call to this with numPoints 2 will have exactly two points: the
start and end points For any points above 2 it will divide it into
numPoints-1 chunks (which means it will generate numPoints-2 vertices other
than the beginning and end). So for 3 points it will divide it in half, 4
points into thirds, and so on.

This is likely to get rather expensive for anything over perhaps a cubic
curve.
package mgl32
import (
	"fmt"
	"math"
)
func Circle(radiusX, radiusY float32, numSlices int) []Vec2 {
	twoPi := float32(2.0 * math.Pi)
	circlePoints := make([]Vec2, 0, numSlices*3)
	center := Vec2{0.0, 0.0}
	previous := Vec2{radiusX, 0.0}
	for theta := twoPi / float32(numSlices); !FloatEqual(theta, twoPi); theta = Clamp(theta+twoPi/float32(numSlices), 0.0, twoPi) {
		sin, cos := math.Sincos(float64(theta))
		curr := Vec2{float32(cos) * radiusX, float32(sin) * radiusY}
		circlePoints = append(circlePoints, center, previous, curr)
		previous = curr
	}
	circlePoints = append(circlePoints, center, previous, Vec2{radiusX, 0.0})
	return circlePoints
}
func Rect(width, height float32) []Vec2 {
	return []Vec2{
		{0.0, 0.0},
		{0.0, -height},
		{width, -height},
		{0.0, 0.0},
		{width, -height},
		{width, 0.0},
	}
}
func QuadraticBezierCurve2D(t float32, cPoint1, cPoint2, cPoint3 Vec2) Vec2 {
	if t < 0.0 || t > 1.0 {
		panic("Can't interpolate on bezier curve with t out of range [0.0,1.0]")
	}
	return cPoint1.Mul((1.0 - t) * (1.0 - t)).Add(cPoint2.Mul(2 * (1 - t) * t)).Add(cPoint3.Mul(t * t))
}
func QuadraticBezierCurve3D(t float32, cPoint1, cPoint2, cPoint3 Vec3) Vec3 {
	if t < 0.0 || t > 1.0 {
		panic("Can't interpolate on bezier curve with t out of range [0.0,1.0]")
	}
	return cPoint1.Mul((1.0 - t) * (1.0 - t)).Add(cPoint2.Mul(2 * (1 - t) * t)).Add(cPoint3.Mul(t * t))
}
func CubicBezierCurve2D(t float32, cPoint1, cPoint2, cPoint3, cPoint4 Vec2) Vec2 {
	if t < 0.0 || t > 1.0 {
		panic("Can't interpolate on bezier curve with t out of range [0.0,1.0]")
	}
	return cPoint1.Mul((1 - t) * (1 - t) * (1 - t)).Add(cPoint2.Mul(3 * (1 - t) * (1 - t) * t)).Add(cPoint3.Mul(3 * (1 - t) * t * t)).Add(cPoint4.Mul(t * t * t))
}
func CubicBezierCurve3D(t float32, cPoint1, cPoint2, cPoint3, cPoint4 Vec3) Vec3 {
	if t < 0.0 || t > 1.0 {
		panic("Can't interpolate on bezier curve with t out of range [0.0,1.0]")
	}
	return cPoint1.Mul((1 - t) * (1 - t) * (1 - t)).Add(cPoint2.Mul(3 * (1 - t) * (1 - t) * t)).Add(cPoint3.Mul(3 * (1 - t) * t * t)).Add(cPoint4.Mul(t * t * t))
}
func BezierCurve2D(t float32, cPoints []Vec2) Vec2 {
	if t < 0.0 || t > 1.0 {
		panic("Input to bezier has t not in range [0,1]. If you think this is a precision error, use mathgl.Clamp[f|d] before calling this function")
	}
	n := len(cPoints) - 1
	point := cPoints[0].Mul(float32(math.Pow(float64(1.0-t), float64(n))))
	for i := 1; i <= n; i++ {
		point = point.Add(cPoints[i].Mul(float32(float64(choose(n, i)) * math.Pow(float64(1-t), float64(n-i)) * math.Pow(float64(t), float64(i)))))  
	}
	return point
}
func BezierCurve3D(t float32, cPoints []Vec3) Vec3 {
	if t < 0.0 || t > 1.0 {
		panic("Input to bezier has t not in range [0,1]. If you think this is a precision error, use mathgl.Clamp[f|d] before calling this function")
	}
	n := len(cPoints) - 1
	point := cPoints[0].Mul(float32(math.Pow(float64(1.0-t), float64(n))))
	for i := 1; i <= n; i++ {
		point = point.Add(cPoints[i].Mul(float32(float64(choose(n, i)) * math.Pow(float64(1-t), float64(n-i)) * math.Pow(float64(t), float64(i)))))  
	}
	return point
}