Lots of line algos
This commit is contained in:
parent
9a4ba6be67
commit
ff7ea1cf25
@ -44,9 +44,12 @@ func main() {
|
|||||||
|
|
||||||
// Just draw a simple line (a million times or something)
|
// Just draw a simple line (a million times or something)
|
||||||
for range LineRepeat {
|
for range LineRepeat {
|
||||||
LineDumb4(&fb, 0xFFFFFF, 100, 100, 350, 200)
|
// LineDumb5(&fb, 0xFFFFFF, 100, 100, 350, 200)
|
||||||
LineDumb4(&fb, 0xFF0000, 120, 100, 200, 350)
|
// LineDumb5(&fb, 0xFF0000, 120, 100, 200, 350)
|
||||||
LineDumb4(&fb, 0xFF0000, 350, 200, 100, 100) // backward first line
|
// LineDumb5(&fb, 0xFF0000, 350, 200, 100, 100) // backward first line
|
||||||
|
Bresenham2(&fb, 0xFFFFFF, 100, 100, 350, 200)
|
||||||
|
Bresenham2(&fb, 0xFF0000, 120, 100, 200, 350)
|
||||||
|
Bresenham2(&fb, 0xFF0000, 350, 200, 100, 100) // backward first line
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Exporting ppm to stdout")
|
log.Printf("Exporting ppm to stdout")
|
||||||
|
@ -92,3 +92,144 @@ func LineDumb4(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For not-steep lines
|
||||||
|
func BresenhamLow(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
||||||
|
dx := x1 - x0
|
||||||
|
dy := y1 - y0
|
||||||
|
yi := 1 // This is the increment
|
||||||
|
if dy < 0 { // Line moves in opposite vertical direction
|
||||||
|
yi = -1
|
||||||
|
dy = -dy
|
||||||
|
}
|
||||||
|
d := 2*dy - dx
|
||||||
|
// Why minus dx? if slope is 0 then d is -dx. If slope is 1 then d = dy.
|
||||||
|
// I don't know...
|
||||||
|
y := y0
|
||||||
|
x1u := uint(x1)
|
||||||
|
for x := uint(x0); x <= x1u; x++ {
|
||||||
|
fb.Set(x, uint(y), color)
|
||||||
|
if d > 0 {
|
||||||
|
y = y + yi
|
||||||
|
d = d + 2*(dy-dx)
|
||||||
|
} else {
|
||||||
|
d = d + 2*dy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For steep lines
|
||||||
|
func BresenhamHigh(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
||||||
|
dx := x1 - x0
|
||||||
|
dy := y1 - y0
|
||||||
|
xi := 1 // This is the increment
|
||||||
|
if dx < 0 { // Line moves in opposite vertical direction
|
||||||
|
xi = -1
|
||||||
|
dx = -dx
|
||||||
|
}
|
||||||
|
d := 2*dx - dy
|
||||||
|
// Why minus dx? if slope is 0 then d is -dx. If slope is 1 then d = dy.
|
||||||
|
// I don't know...
|
||||||
|
x := x0
|
||||||
|
y1u := uint(y1)
|
||||||
|
for y := uint(y0); y <= y1u; y++ {
|
||||||
|
fb.Set(uint(x), y, color)
|
||||||
|
if d > 0 {
|
||||||
|
x = x + xi
|
||||||
|
d = d + 2*(dx-dy)
|
||||||
|
} else {
|
||||||
|
d = d + 2*dx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bresenham(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
||||||
|
if math.Abs(float64(y1-y0)) < math.Abs(float64(x1-x0)) { // This is a flatter line
|
||||||
|
if x0 > x1 { // This line is backwards
|
||||||
|
BresenhamLow(fb, color, x1, y1, x0, y0)
|
||||||
|
} else {
|
||||||
|
BresenhamLow(fb, color, x0, y0, x1, y1)
|
||||||
|
}
|
||||||
|
} else { // This is a steep line
|
||||||
|
if y0 > y1 { // This line is backwards
|
||||||
|
BresenhamHigh(fb, color, x1, y1, x0, y0)
|
||||||
|
} else {
|
||||||
|
BresenhamHigh(fb, color, x0, y0, x1, y1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Bresenham2(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
||||||
|
dx := int(math.Abs(float64(x1 - x0)))
|
||||||
|
sx := -1
|
||||||
|
if x0 < x1 {
|
||||||
|
sx = 1
|
||||||
|
}
|
||||||
|
dy := -int(math.Abs(float64(y1 - y0)))
|
||||||
|
sy := -1
|
||||||
|
if y0 < y1 {
|
||||||
|
sy = 1
|
||||||
|
}
|
||||||
|
err := dx + dy
|
||||||
|
|
||||||
|
for {
|
||||||
|
fb.Set(uint(x0), uint(y0), color)
|
||||||
|
if x0 == x1 && y0 == y1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
e2 := 2 * err
|
||||||
|
if e2 >= dy {
|
||||||
|
if x0 == x1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
err += dy
|
||||||
|
x0 += sx
|
||||||
|
}
|
||||||
|
if e2 <= dx {
|
||||||
|
if y0 == y1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
err += dx
|
||||||
|
y0 += sy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LineDumb5(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
||||||
|
steep := false
|
||||||
|
// This one makes sure that going pixel by pixel will not make holes in the
|
||||||
|
// other direction by always moving in the less steep direction.
|
||||||
|
if math.Abs(float64(x1-x0)) < math.Abs(float64(y1-y0)) {
|
||||||
|
x0, y0 = y0, x0
|
||||||
|
x1, y1 = y1, x1
|
||||||
|
steep = true
|
||||||
|
}
|
||||||
|
// Don't let lines be invisible, always go left to right
|
||||||
|
if x0 > x1 { // need to be left to right
|
||||||
|
x0, x1 = x1, x0
|
||||||
|
y0, y1 = y1, y0 // Why are we swapping these? I guess because we're swapping the points...
|
||||||
|
}
|
||||||
|
dx := x1 - x0 // These MUST be POST calcs
|
||||||
|
dy := y1 - y0
|
||||||
|
derror2 := int(math.Abs(float64(dy))) * 2
|
||||||
|
error2 := 0
|
||||||
|
y := y0
|
||||||
|
sy := 1
|
||||||
|
if y1 <= y0 {
|
||||||
|
sy = -1
|
||||||
|
}
|
||||||
|
// Same as dumb2, going across pixel by pixel. But "x" here might actually be y
|
||||||
|
// because of the inverted direction
|
||||||
|
for x := x0; x <= x1; x++ {
|
||||||
|
if steep {
|
||||||
|
fb.Set(uint(y), uint(x), color)
|
||||||
|
} else {
|
||||||
|
fb.Set(uint(x), uint(y), color)
|
||||||
|
}
|
||||||
|
error2 += derror2
|
||||||
|
if error2 > dx {
|
||||||
|
y = y + sy
|
||||||
|
error2 -= dx * 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user