184 lines
3.7 KiB
Go
184 lines
3.7 KiB
Go
package bresenham
|
|
|
|
import (
|
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
|
)
|
|
|
|
// dx > dy; x1 < x2; y1 < y2
|
|
func BresenhamDxXRYD(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
|
|
dx, dy := To.X - From.X, 2*(To.Y - From.Y)
|
|
e, slope := dx, 2*dx
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
e -= dy
|
|
if e < 0 {
|
|
From.Y++
|
|
e += slope
|
|
}
|
|
}
|
|
}
|
|
|
|
// dy > dx; x1 < x2; y1 < y2
|
|
func BresenhamDyXRYD(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
|
|
dx, dy := 2*(To.X - From.X), To.Y - From.Y
|
|
e, slope := dy, 2*dy
|
|
for ; dy != 0; dy-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.Y++
|
|
e -= dx
|
|
if e < 0 {
|
|
From.X++
|
|
e += slope
|
|
}
|
|
}
|
|
}
|
|
|
|
// dx > dy; x1 < x2; y1 > y2
|
|
func BresenhamDxXRYU(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
|
|
dx, dy := To.X - From.X, 2*(From.Y-To.Y)
|
|
e, slope := dx, 2*dx
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
e -= dy
|
|
if e < 0 {
|
|
From.Y--
|
|
e += slope
|
|
}
|
|
}
|
|
}
|
|
|
|
func BresenhamDyXRYU(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
|
|
dx, dy := 2*(To.X - From.X), From.Y-To.Y
|
|
e, slope := dy, 2*dy
|
|
for ; dy != 0; dy-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.Y--
|
|
e -= dx
|
|
if e < 0 {
|
|
From.X++
|
|
e += slope
|
|
}
|
|
}
|
|
}
|
|
|
|
// Generalized with integer
|
|
func Bresenham(canvas types.Putable, From, To types.Coords, symFunc func() interface{}) {
|
|
var dx, dy, e, slope int
|
|
|
|
// Because drawing p1 -> p2 is equivalent to draw p2 -> p1,
|
|
// I sort points in x-axis order to handle only half of possible cases.
|
|
if From.X > To.X {
|
|
From.X, From.Y, To.X, To.Y = To.X, To.Y, From.X, From.Y
|
|
}
|
|
|
|
dx, dy = To.X - From.X, To.Y - From.Y
|
|
// Because point is x-axis ordered, dx cannot be negative
|
|
if dy < 0 {
|
|
dy = -dy
|
|
}
|
|
|
|
switch {
|
|
|
|
// Is line a point ?
|
|
case From.X ==To.X && From.Y ==To.Y:
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
|
|
// Is line an horizontal ?
|
|
case From.Y ==To.Y:
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
}
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
|
|
// Is line a vertical ?
|
|
case From.X ==To.X:
|
|
if From.Y > To.Y {
|
|
From.Y, To.Y = To.Y, From.Y
|
|
}
|
|
for ; dy != 0; dy-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.Y++
|
|
}
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
|
|
// Is line a diagonal ?
|
|
case dx == dy:
|
|
if From.Y < To.Y {
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
From.Y++
|
|
}
|
|
} else {
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
From.Y--
|
|
}
|
|
}
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
|
|
// wider than high ?
|
|
case dx > dy:
|
|
if From.Y < To.Y {
|
|
// BresenhamDxXRYD(img, x1, y1, x2, y2, col)
|
|
dy, e, slope = 2*dy, dx, 2*dx
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
e -= dy
|
|
if e < 0 {
|
|
From.Y++
|
|
e += slope
|
|
}
|
|
}
|
|
} else {
|
|
// BresenhamDxXRYU(img, x1, y1, x2, y2, col)
|
|
dy, e, slope = 2*dy, dx, 2*dx
|
|
for ; dx != 0; dx-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.X++
|
|
e -= dy
|
|
if e < 0 {
|
|
From.Y--
|
|
e += slope
|
|
}
|
|
}
|
|
}
|
|
canvas.Put(To.X, To.Y, symFunc())
|
|
|
|
// higher than wide.
|
|
default:
|
|
if From.Y < To.Y {
|
|
// BresenhamDyXRYD(img, x1, y1, x2, y2, col)
|
|
dx, e, slope = 2*dx, dy, 2*dy
|
|
for ; dy != 0; dy-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.Y++
|
|
e -= dx
|
|
if e < 0 {
|
|
From.X++
|
|
e += slope
|
|
}
|
|
}
|
|
} else {
|
|
// BresenhamDyXRYU(img, x1, y1, x2, y2, col)
|
|
dx, e, slope = 2*dx, dy, 2*dy
|
|
for ; dy != 0; dy-- {
|
|
canvas.Put(From.X, From.Y, symFunc())
|
|
From.Y--
|
|
e -= dx
|
|
if e < 0 {
|
|
From.X++
|
|
e += slope
|
|
}
|
|
}
|
|
}
|
|
canvas.Put(To.X, To.Y, symFunc())
|
|
//img.Set(x2, y2, col)
|
|
}
|
|
}
|