|
|
@@ -10,33 +10,41 @@ import (
|
|
|
"math"
|
|
|
)
|
|
|
|
|
|
-// Circle represents a circle geometry
|
|
|
+// Circle represents the geometry of a filled circle (i.e. a disk)
|
|
|
+// The center of the circle is at the origin, and theta runs counter-clockwise
|
|
|
+// on the XY plane, starting at (x,y,z)=(1,0,0).
|
|
|
type Circle struct {
|
|
|
Geometry
|
|
|
Radius float64
|
|
|
- Segments int
|
|
|
+ Segments int // >= 3
|
|
|
ThetaStart float64
|
|
|
ThetaLength float64
|
|
|
}
|
|
|
|
|
|
-// NewCircle creates and returns a pointer to a new Circle geometry object.
|
|
|
-// The geometry is defined by its radius, the number of segments (triangles), minimum = 3,
|
|
|
-// the start angle in radians for the first segment (thetaStart) and
|
|
|
-// the central angle in radians (thetaLength) of the circular sector.
|
|
|
-func NewCircle(radius float64, segments int, thetaStart, thetaLength float64) *Circle {
|
|
|
+// NewCircle creates a new circle geometry with the specified radius
|
|
|
+// and number of radial segments/triangles (minimum 3).
|
|
|
+func NewCircle(radius float64, segments int) *Circle {
|
|
|
+ return NewCircleSector(radius, segments, 0, 2*math.Pi)
|
|
|
+}
|
|
|
+
|
|
|
+// NewCircleSector creates a new circle or circular sector geometry with the specified radius,
|
|
|
+// number of radial segments/triangles (minimum 3), sector start angle in radians (thetaStart),
|
|
|
+// and sector size angle in radians (thetaLength). This is the Circle constructor with most tunable parameters.
|
|
|
+func NewCircleSector(radius float64, segments int, thetaStart, thetaLength float64) *Circle {
|
|
|
|
|
|
circ := new(Circle)
|
|
|
circ.Geometry.Init()
|
|
|
|
|
|
+ // Validate arguments
|
|
|
+ if segments < 3 {
|
|
|
+ panic("Invalid argument: segments. The number of segments needs to be greater or equal to 3.")
|
|
|
+ }
|
|
|
+
|
|
|
circ.Radius = radius
|
|
|
circ.Segments = segments
|
|
|
circ.ThetaStart = thetaStart
|
|
|
circ.ThetaLength = thetaLength
|
|
|
|
|
|
- if segments < 3 {
|
|
|
- segments = 3
|
|
|
- }
|
|
|
-
|
|
|
// Create buffers
|
|
|
positions := math32.NewArrayF32(0, 16)
|
|
|
normals := math32.NewArrayF32(0, 16)
|
|
|
@@ -52,10 +60,11 @@ func NewCircle(radius float64, segments int, thetaStart, thetaLength float64) *C
|
|
|
normal.Z = 1
|
|
|
normals.AppendVector3(&normal)
|
|
|
|
|
|
- // Append circle center uv coord
|
|
|
+ // Append circle center uv coordinate
|
|
|
centerUV := math32.NewVector2(0.5, 0.5)
|
|
|
uvs.AppendVector2(centerUV)
|
|
|
|
|
|
+ // Generate the segments
|
|
|
for i := 0; i <= segments; i++ {
|
|
|
segment := thetaStart + float64(i)/float64(segments)*thetaLength
|
|
|
|