commit 79d7e1e43ddc27a68c5ee4f5caf56f8b42d185e9 Author: Evan Burkey Date: Tue May 17 09:20:48 2022 -0700 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..609aded --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2022 Evan Burkey + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5297241 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Bresenham + +A quick generic implementation of Bresenham's Line Algorithm. + +## Usage + +Arguments are constrained to signed types. The line is returned as a slice of type `Point[T]`, a type provided by the library. \ No newline at end of file diff --git a/bresenham.go b/bresenham.go new file mode 100644 index 0000000..f57830b --- /dev/null +++ b/bresenham.go @@ -0,0 +1,58 @@ +// Package bresenham provides a generic implementation of +// Bresenham's Line Algorithm +package bresenham + +import "golang.org/x/exp/constraints" + +// Point is a generic struct holding two generic coordinates +// with a constraint of Signed +type Point[T constraints.Signed] struct { + X T + Y T +} + +func abs[T constraints.Signed](a T) T { + if a < 0 { + return -a + } + return a +} + +// Bresenham requires arguments of any signed type. The line is generated +// and returned as a slice of Point[T] +func Bresenham[T constraints.Signed](x0, y0, x1, y1 T) []Point[T] { + var line []Point[T] + var cx, cy, dx, dy, sx, sy, err T + cx = x0 + cy = y0 + dx = abs(x1 - x0) + dy = abs(y1 - y0) + + if cx < x1 { + sx = 1 + } else { + sx = -1 + } + if cy < y1 { + sy = 1 + } else { + sy = -1 + } + err = dx - dy + + for { + line = append(line, Point[T]{cx, cy}) + if cx == x1 && cy == y1 { + return line + } + e2 := 2 * err + if e2 > 0-dy { + err = err - dy + cx = cx + sx + } + if e2 < dx { + err = err + dx + cy = cy + sy + } + } +} diff --git a/bresenham_test.go b/bresenham_test.go new file mode 100644 index 0000000..a1f813c --- /dev/null +++ b/bresenham_test.go @@ -0,0 +1,53 @@ +package bresenham + +import ( + "testing" +) + +func TestBresenhamInt(t *testing.T) { + var x0, y0, x1, y1 int + x0 = 1 + y0 = 1 + x1 = 3 + y1 = 4 + res := []Point[int]{ + {1, 1}, {2, 2}, {2, 3}, {3, 4}, + } + + line := Bresenham(x0, y0, x1, y1) + if line[0].X != res[0].X && line[0].Y != line[0].Y { + t.Errorf("Wanted %d,%d, got %d,%d", res[0].X, res[0].Y, line[0].X, line[0].Y) + } +} + +func TestBresenhamIntNegative(t *testing.T) { + var x0, y0, x1, y1 int + x0 = -1 + y0 = 2 + x1 = 3 + y1 = -4 + res := []Point[int]{ + {-1, 2}, {0, 1}, {0, 0}, {1, -1}, {2, -2}, {2, -3}, {3, -4}, + } + + line := Bresenham(x0, y0, x1, y1) + if line[0].X != res[0].X && line[0].Y != line[0].Y { + t.Errorf("Wanted %d,%d, got %d,%d", res[0].X, res[0].Y, line[0].X, line[0].Y) + } +} + +func TestBresenhamInt64(t *testing.T) { + var x0, y0, x1, y1 int64 + x0 = 1 + y0 = 1 + x1 = 3 + y1 = 4 + res := []Point[int64]{ + {1, 1}, {2, 2}, {2, 3}, {3, 4}, + } + + line := Bresenham(x0, y0, x1, y1) + if line[0].X != res[0].X && line[0].Y != line[0].Y { + t.Errorf("Wanted %d,%d, got %d,%d", res[0].X, res[0].Y, line[0].X, line[0].Y) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1630c26 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module bresenham + +go 1.18 + +require golang.org/x/exp v0.0.0-20220516143420-24438e51023a // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..977085d --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/exp v0.0.0-20220516143420-24438e51023a h1:tiLLxEjKNE6Hrah/Dp/cyHvsyjDLcMFSocOHO5XDmOM= +golang.org/x/exp v0.0.0-20220516143420-24438e51023a/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=