init
This commit is contained in:
commit
79d7e1e43d
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.idea
|
13
LICENSE
Normal file
13
LICENSE
Normal file
@ -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.
|
7
README.md
Normal file
7
README.md
Normal file
@ -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.
|
58
bresenham.go
Normal file
58
bresenham.go
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
bresenham_test.go
Normal file
53
bresenham_test.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module bresenham
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require golang.org/x/exp v0.0.0-20220516143420-24438e51023a // indirect
|
Loading…
x
Reference in New Issue
Block a user