init
This commit is contained in:
		
							
								
								
									
										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 | ||||||
		Reference in New Issue
	
	Block a user