Commit Diff


commit - /dev/null
commit + 79d7e1e43ddc27a68c5ee4f5caf56f8b42d185e9
blob - /dev/null
blob + 723ef36f4e4f32c4560383aa5987c575a30c6535 (mode 644)
--- /dev/null
+++ .gitignore
@@ -0,0 +1 @@
+.idea
\ No newline at end of file
blob - /dev/null
blob + 609adedb29f4a1a310a5cc107f2f27bf3160f308 (mode 644)
--- /dev/null
+++ LICENSE
@@ -0,0 +1,13 @@
+Copyright 2022 Evan Burkey <dev@fputs.com>
+
+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.
blob - /dev/null
blob + 5297241ab248929cb1c0c1930cd83d244f3676a6 (mode 644)
--- /dev/null
+++ 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
blob - /dev/null
blob + f57830b9274cfa165f56c88d362bea193f41a446 (mode 644)
--- /dev/null
+++ 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
+		}
+	}
+}
blob - /dev/null
blob + a1f813c5004ce9daeec4875e8e841411ae73fc19 (mode 644)
--- /dev/null
+++ 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)
+	}
+}
blob - /dev/null
blob + 1630c26a7cc419b67f3789ce9f571540d39a8435 (mode 644)
--- /dev/null
+++ go.mod
@@ -0,0 +1,5 @@
+module bresenham
+
+go 1.18
+
+require golang.org/x/exp v0.0.0-20220516143420-24438e51023a // indirect
blob - /dev/null
blob + 977085d7497f98cff2f8b22a1dbab1ff8de4393c (mode 644)
--- /dev/null
+++ 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=