doodle/lib/render/ellipse.go

65 lines
1.5 KiB
Go
Raw Normal View History

2019-07-17 01:27:00 +00:00
package render
// MidpointEllipse implements an ellipse plotting algorithm.
func MidpointEllipse(center, radius Point) chan Point {
yield := make(chan Point)
go func() {
var (
pos = NewPoint(radius.X, 0)
delta = NewPoint(
2*radius.Y*radius.Y*pos.X,
2*radius.X*radius.X*pos.Y,
)
err = radius.X*radius.X -
radius.Y*radius.Y*radius.X +
(radius.Y*radius.Y)/4
)
for delta.Y < delta.X {
yield <- NewPoint(center.X+pos.X, center.Y+pos.Y)
yield <- NewPoint(center.X+pos.X, center.Y-pos.Y)
yield <- NewPoint(center.X-pos.X, center.Y+pos.Y)
yield <- NewPoint(center.X-pos.X, center.Y-pos.Y)
pos.Y++
if err < 0 {
delta.Y += 2 * radius.X * radius.X
err += delta.Y + radius.X*radius.X
} else {
pos.X--
delta.Y += 2 * radius.X * radius.X
delta.X -= 2 * radius.Y * radius.Y
err += delta.Y - delta.X + radius.X*radius.X
}
}
err = radius.X*radius.X*(pos.Y*pos.Y+pos.Y) +
radius.Y*radius.Y*(pos.X-1)*(pos.X-1) -
radius.Y*radius.Y*radius.X*radius.X
for pos.X >= 0 {
yield <- NewPoint(center.X+pos.X, center.Y+pos.Y)
yield <- NewPoint(center.X+pos.X, center.Y-pos.Y)
yield <- NewPoint(center.X-pos.X, center.Y+pos.Y)
yield <- NewPoint(center.X-pos.X, center.Y-pos.Y)
pos.X--
if err > 0 {
delta.X -= 2 * radius.Y * radius.Y
err += radius.Y*radius.Y - delta.X
} else {
pos.Y++
delta.Y += 2 * radius.X * radius.X
delta.X -= 2 * radius.Y * radius.Y
err += delta.Y - delta.X + radius.Y*radius.Y
}
}
close(yield)
}()
return yield
}