修改范型类型为带符号数字及float

This commit is contained in:
kercylan 2023-06-18 13:55:26 +08:00
parent e5b092a75f
commit 7ee7a674d7
6 changed files with 54 additions and 50 deletions

View File

@ -8,6 +8,10 @@ type Number interface {
Integer | Float Integer | Float
} }
type SignedNumber interface {
Signed | Float
}
type Integer interface { type Integer interface {
Signed | Unsigned Signed | Unsigned
} }

View File

@ -37,7 +37,7 @@ func GetOppositionDirection(direction Direction) Direction {
} }
// GetDirectionNextWithCoordinate 获取特定方向上的下一个坐标 // GetDirectionNextWithCoordinate 获取特定方向上的下一个坐标
func GetDirectionNextWithCoordinate[V generic.Number](direction Direction, x, y V) (nx, ny V) { func GetDirectionNextWithCoordinate[V generic.SignedNumber](direction Direction, x, y V) (nx, ny V) {
switch direction { switch direction {
case DirectionUp: case DirectionUp:
nx, ny = x, y-1 nx, ny = x, y-1
@ -54,7 +54,7 @@ func GetDirectionNextWithCoordinate[V generic.Number](direction Direction, x, y
} }
// GetDirectionNextWithCoordinateArray 获取特定方向上的下一个坐标 // GetDirectionNextWithCoordinateArray 获取特定方向上的下一个坐标
func GetDirectionNextWithCoordinateArray[V generic.Number](direction Direction, point Point[V]) Point[V] { func GetDirectionNextWithCoordinateArray[V generic.SignedNumber](direction Direction, point Point[V]) Point[V] {
x, y := point.GetXY() x, y := point.GetXY()
switch direction { switch direction {
case DirectionUp: case DirectionUp:
@ -72,7 +72,7 @@ func GetDirectionNextWithCoordinateArray[V generic.Number](direction Direction,
// GetDirectionNextWithPos 获取位置在特定宽度和特定方向上的下一个位置 // GetDirectionNextWithPos 获取位置在特定宽度和特定方向上的下一个位置
// - 需要注意的是,在左右方向时,当下一个位置不在游戏区域内时,将会返回上一行的末位置或下一行的首位置 // - 需要注意的是,在左右方向时,当下一个位置不在游戏区域内时,将会返回上一行的末位置或下一行的首位置
func GetDirectionNextWithPos[V generic.Number](direction Direction, width, pos V) V { func GetDirectionNextWithPos[V generic.SignedNumber](direction Direction, width, pos V) V {
switch direction { switch direction {
case DirectionUp: case DirectionUp:
return pos - width return pos - width
@ -88,7 +88,7 @@ func GetDirectionNextWithPos[V generic.Number](direction Direction, width, pos V
} }
// CalcDirection 计算点2位于点1的方向 // CalcDirection 计算点2位于点1的方向
func CalcDirection[V generic.Number](x1, y1, x2, y2 V) Direction { func CalcDirection[V generic.SignedNumber](x1, y1, x2, y2 V) Direction {
var oneEighty = 180 var oneEighty = 180
var fortyFive = 45 var fortyFive = 45
var oneThirtyFive = 135 var oneThirtyFive = 135
@ -110,17 +110,17 @@ func CalcDirection[V generic.Number](x1, y1, x2, y2 V) Direction {
} }
// CalcDistance 计算两点之间的距离 // CalcDistance 计算两点之间的距离
func CalcDistance[V generic.Number](x1, y1, x2, y2 V) V { func CalcDistance[V generic.SignedNumber](x1, y1, x2, y2 V) V {
return V(math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2))) return V(math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2)))
} }
// CalcAngle 计算点2位于点1之间的角度 // CalcAngle 计算点2位于点1之间的角度
func CalcAngle[V generic.Number](x1, y1, x2, y2 V) V { func CalcAngle[V generic.SignedNumber](x1, y1, x2, y2 V) V {
return V(math.Atan2(float64(y2-y1), float64(x2-x1)) * 180 / math.Pi) return V(math.Atan2(float64(y2-y1), float64(x2-x1)) * 180 / math.Pi)
} }
// CalculateNewCoordinate 根据给定的x、y坐标、角度和距离计算新的坐标 // CalculateNewCoordinate 根据给定的x、y坐标、角度和距离计算新的坐标
func CalculateNewCoordinate[V generic.Number](x, y, angle, distance V) (newX, newY V) { func CalculateNewCoordinate[V generic.SignedNumber](x, y, angle, distance V) (newX, newY V) {
// 将角度转换为弧度 // 将角度转换为弧度
var pi = math.Pi var pi = math.Pi
var dividend = 180.0 var dividend = 180.0

View File

@ -5,12 +5,12 @@ import (
) )
// PointOnLineWithCoordinate 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上 // PointOnLineWithCoordinate 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
func PointOnLineWithCoordinate[V generic.Number](x1, y1, x2, y2, x, y V) bool { func PointOnLineWithCoordinate[V generic.SignedNumber](x1, y1, x2, y2, x, y V) bool {
return (x-x1)*(y2-y1) == (x2-x1)*(y-y1) return (x-x1)*(y2-y1) == (x2-x1)*(y-y1)
} }
// PointOnLineWithPos 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上 // PointOnLineWithPos 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
func PointOnLineWithPos[V generic.Number](width, pos1, pos2, pos V) bool { func PointOnLineWithPos[V generic.SignedNumber](width, pos1, pos2, pos V) bool {
x1, y1 := PosToCoordinate(width, pos1) x1, y1 := PosToCoordinate(width, pos1)
x2, y2 := PosToCoordinate(width, pos2) x2, y2 := PosToCoordinate(width, pos2)
x, y := PosToCoordinate(width, pos) x, y := PosToCoordinate(width, pos)
@ -18,7 +18,7 @@ func PointOnLineWithPos[V generic.Number](width, pos1, pos2, pos V) bool {
} }
// PointOnLineWithCoordinateArray 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上 // PointOnLineWithCoordinateArray 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
func PointOnLineWithCoordinateArray[V generic.Number](point1, point2, point Point[V]) bool { func PointOnLineWithCoordinateArray[V generic.SignedNumber](point1, point2, point Point[V]) bool {
x1, y1 := point1.GetXY() x1, y1 := point1.GetXY()
x2, y2 := point2.GetXY() x2, y2 := point2.GetXY()
x, y := point.GetXY() x, y := point.GetXY()
@ -27,13 +27,13 @@ func PointOnLineWithCoordinateArray[V generic.Number](point1, point2, point Poin
// PointOnSegmentWithCoordinate 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上 // PointOnSegmentWithCoordinate 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
// - 与 PointOnLineWithCoordinate 不同的是, PointOnSegmentWithCoordinate 中会判断线段及点的位置是否正确 // - 与 PointOnLineWithCoordinate 不同的是, PointOnSegmentWithCoordinate 中会判断线段及点的位置是否正确
func PointOnSegmentWithCoordinate[V generic.Number](x1, y1, x2, y2, x, y V) bool { func PointOnSegmentWithCoordinate[V generic.SignedNumber](x1, y1, x2, y2, x, y V) bool {
return x >= x1 && x <= x2 && y >= y1 && y <= y2 && PointOnLineWithCoordinate(x1, y1, x2, y2, x, y) return x >= x1 && x <= x2 && y >= y1 && y <= y2 && PointOnLineWithCoordinate(x1, y1, x2, y2, x, y)
} }
// PointOnSegmentWithPos 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上 // PointOnSegmentWithPos 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
// - 与 PointOnLineWithPos 不同的是, PointOnSegmentWithPos 中会判断线段及点的位置是否正确 // - 与 PointOnLineWithPos 不同的是, PointOnSegmentWithPos 中会判断线段及点的位置是否正确
func PointOnSegmentWithPos[V generic.Number](width, pos1, pos2, pos V) bool { func PointOnSegmentWithPos[V generic.SignedNumber](width, pos1, pos2, pos V) bool {
x1, y1 := PosToCoordinate(width, pos1) x1, y1 := PosToCoordinate(width, pos1)
x2, y2 := PosToCoordinate(width, pos2) x2, y2 := PosToCoordinate(width, pos2)
x, y := PosToCoordinate(width, pos) x, y := PosToCoordinate(width, pos)
@ -42,7 +42,7 @@ func PointOnSegmentWithPos[V generic.Number](width, pos1, pos2, pos V) bool {
// PointOnSegmentWithCoordinateArray 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上 // PointOnSegmentWithCoordinateArray 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
// - 与 PointOnLineWithCoordinateArray 不同的是, PointOnSegmentWithCoordinateArray 中会判断线段及点的位置是否正确 // - 与 PointOnLineWithCoordinateArray 不同的是, PointOnSegmentWithCoordinateArray 中会判断线段及点的位置是否正确
func PointOnSegmentWithCoordinateArray[V generic.Number](point1, point2, point Point[V]) bool { func PointOnSegmentWithCoordinateArray[V generic.SignedNumber](point1, point2, point Point[V]) bool {
x1, y1 := point1.GetXY() x1, y1 := point1.GetXY()
x2, y2 := point2.GetXY() x2, y2 := point2.GetXY()
x, y := point.GetXY() x, y := point.GetXY()

View File

@ -6,10 +6,10 @@ import (
) )
// Point 表示了一个由 x、y 坐标组成的点 // Point 表示了一个由 x、y 坐标组成的点
type Point[V generic.Number] [2]V type Point[V generic.SignedNumber] [2]V
// NewPoint 创建一个由 x、y 坐标组成的点 // NewPoint 创建一个由 x、y 坐标组成的点
func NewPoint[V generic.Number](x, y V) Point[V] { func NewPoint[V generic.SignedNumber](x, y V) Point[V] {
return Point[V]{x, y} return Point[V]{x, y}
} }
@ -54,14 +54,14 @@ func (slf Point[V]) Copy() Point[V] {
} }
// NewPointCap 创建一个由 x、y 坐标组成的点,这个点具有一个数据容量 // NewPointCap 创建一个由 x、y 坐标组成的点,这个点具有一个数据容量
func NewPointCap[V generic.Number, D any](x, y V) PointCap[V, D] { func NewPointCap[V generic.SignedNumber, D any](x, y V) PointCap[V, D] {
return PointCap[V, D]{ return PointCap[V, D]{
Point: NewPoint(x, y), Point: NewPoint(x, y),
} }
} }
// NewPointCapWithData 通过设置数据的方式创建一个由 x、y 坐标组成的点,这个点具有一个数据容量 // NewPointCapWithData 通过设置数据的方式创建一个由 x、y 坐标组成的点,这个点具有一个数据容量
func NewPointCapWithData[V generic.Number, D any](x, y V, data D) PointCap[V, D] { func NewPointCapWithData[V generic.SignedNumber, D any](x, y V, data D) PointCap[V, D] {
return PointCap[V, D]{ return PointCap[V, D]{
Point: NewPoint(x, y), Point: NewPoint(x, y),
Data: data, Data: data,
@ -69,7 +69,7 @@ func NewPointCapWithData[V generic.Number, D any](x, y V, data D) PointCap[V, D]
} }
// PointCap 表示了一个由 x、y 坐标组成的点,这个点具有一个数据容量 // PointCap 表示了一个由 x、y 坐标组成的点,这个点具有一个数据容量
type PointCap[V generic.Number, D any] struct { type PointCap[V generic.SignedNumber, D any] struct {
Point[V] Point[V]
Data D Data D
} }
@ -80,29 +80,29 @@ func (slf PointCap[V, D]) GetData() D {
} }
// CoordinateToCoordinateArray 将坐标转换为x、y的坐标数组 // CoordinateToCoordinateArray 将坐标转换为x、y的坐标数组
func CoordinateToCoordinateArray[V generic.Number](x, y V) Point[V] { func CoordinateToCoordinateArray[V generic.SignedNumber](x, y V) Point[V] {
return [2]V{x, y} return [2]V{x, y}
} }
// CoordinateToPos 将坐标转换为二维数组的顺序位置坐标 // CoordinateToPos 将坐标转换为二维数组的顺序位置坐标
// - 需要确保x的取值范围必须小于width或者将会得到不正确的值 // - 需要确保x的取值范围必须小于width或者将会得到不正确的值
func CoordinateToPos[V generic.Number](width, x, y V) V { func CoordinateToPos[V generic.SignedNumber](width, x, y V) V {
return y*width + x return y*width + x
} }
// CoordinateArrayToCoordinate 将坐标数组转换为x和y坐标 // CoordinateArrayToCoordinate 将坐标数组转换为x和y坐标
func CoordinateArrayToCoordinate[V generic.Number](position Point[V]) (x, y V) { func CoordinateArrayToCoordinate[V generic.SignedNumber](position Point[V]) (x, y V) {
return position[0], position[1] return position[0], position[1]
} }
// CoordinateArrayToPos 将坐标转换为二维数组的顺序位置 // CoordinateArrayToPos 将坐标转换为二维数组的顺序位置
// - 需要确保x的取值范围必须小于width或者将会得到不正确的值 // - 需要确保x的取值范围必须小于width或者将会得到不正确的值
func CoordinateArrayToPos[V generic.Number](width V, xy Point[V]) V { func CoordinateArrayToPos[V generic.SignedNumber](width V, xy Point[V]) V {
return CoordinateToPos(width, xy[0], xy[1]) return CoordinateToPos(width, xy[0], xy[1])
} }
// PosToCoordinate 通过宽度将一个二维数组的顺序位置转换为xy坐标 // PosToCoordinate 通过宽度将一个二维数组的顺序位置转换为xy坐标
func PosToCoordinate[V generic.Number](width, pos V) (x, y V) { func PosToCoordinate[V generic.SignedNumber](width, pos V) (x, y V) {
x = V(math.Mod(float64(pos), float64(width))) x = V(math.Mod(float64(pos), float64(width)))
y = pos / width y = pos / width
@ -110,28 +110,28 @@ func PosToCoordinate[V generic.Number](width, pos V) (x, y V) {
} }
// PosToCoordinateArray 通过宽度将一个二维数组的顺序位置转换为x、y的坐标数组 // PosToCoordinateArray 通过宽度将一个二维数组的顺序位置转换为x、y的坐标数组
func PosToCoordinateArray[V generic.Number](width, pos V) Point[V] { func PosToCoordinateArray[V generic.SignedNumber](width, pos V) Point[V] {
return [2]V{V(math.Mod(float64(pos), float64(width))), pos / width} return [2]V{V(math.Mod(float64(pos), float64(width))), pos / width}
} }
// PosToCoordinateX 通过宽度将一个二维数组的顺序位置转换为X坐标 // PosToCoordinateX 通过宽度将一个二维数组的顺序位置转换为X坐标
func PosToCoordinateX[V generic.Number](width, pos V) V { func PosToCoordinateX[V generic.SignedNumber](width, pos V) V {
return V(math.Mod(float64(pos), float64(width))) return V(math.Mod(float64(pos), float64(width)))
} }
// PosToCoordinateY 通过宽度将一个二维数组的顺序位置转换为Y坐标 // PosToCoordinateY 通过宽度将一个二维数组的顺序位置转换为Y坐标
func PosToCoordinateY[V generic.Number](width, pos V) V { func PosToCoordinateY[V generic.SignedNumber](width, pos V) V {
return pos / width return pos / width
} }
// CoordinateArrayCopy 复制一个坐标数组 // CoordinateArrayCopy 复制一个坐标数组
func CoordinateArrayCopy[V generic.Number](position Point[V]) Point[V] { func CoordinateArrayCopy[V generic.SignedNumber](position Point[V]) Point[V] {
return NewPoint(position[0], position[1]) return NewPoint(position[0], position[1])
} }
// CoordinateArrayToPosWithMulti 将一组坐标转换为二维数组的顺序位置 // CoordinateArrayToPosWithMulti 将一组坐标转换为二维数组的顺序位置
// - 需要确保x的取值范围必须小于width或者将会得到不正确的值 // - 需要确保x的取值范围必须小于width或者将会得到不正确的值
func CoordinateArrayToPosWithMulti[V generic.Number](width V, xys ...Point[V]) []V { func CoordinateArrayToPosWithMulti[V generic.SignedNumber](width V, xys ...Point[V]) []V {
var result = make([]V, len(xys), len(xys)) var result = make([]V, len(xys), len(xys))
for i := 0; i < len(xys); i++ { for i := 0; i < len(xys); i++ {
result[i] = CoordinateArrayToPos(width, xys[i]) result[i] = CoordinateArrayToPos(width, xys[i])
@ -140,7 +140,7 @@ func CoordinateArrayToPosWithMulti[V generic.Number](width V, xys ...Point[V]) [
} }
// PosToCoordinateArrayWithMulti 将一组二维数组的顺序位置转换为一组数组坐标 // PosToCoordinateArrayWithMulti 将一组二维数组的顺序位置转换为一组数组坐标
func PosToCoordinateArrayWithMulti[V generic.Number](width V, positions ...V) []Point[V] { func PosToCoordinateArrayWithMulti[V generic.SignedNumber](width V, positions ...V) []Point[V] {
var result = make([]Point[V], len(positions)) var result = make([]Point[V], len(positions))
for i := 0; i < len(positions); i++ { for i := 0; i < len(positions); i++ {
result[i] = PosToCoordinateArray(width, positions[i]) result[i] = PosToCoordinateArray(width, positions[i])
@ -149,6 +149,6 @@ func PosToCoordinateArrayWithMulti[V generic.Number](width V, positions ...V) []
} }
// PosSameRow 返回两个顺序位置在同一宽度是否位于同一行 // PosSameRow 返回两个顺序位置在同一宽度是否位于同一行
func PosSameRow[V generic.Number](width, pos1, pos2 V) bool { func PosSameRow[V generic.SignedNumber](width, pos1, pos2 V) bool {
return (pos1 / width) == (pos2 / width) return (pos1 / width) == (pos2 / width)
} }

View File

@ -3,7 +3,7 @@ package geometry
import "github.com/kercylan98/minotaur/utils/generic" import "github.com/kercylan98/minotaur/utils/generic"
// GetAdjacentTranslatePos 获取一个连续位置的矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置 // GetAdjacentTranslatePos 获取一个连续位置的矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
func GetAdjacentTranslatePos[T any, P generic.Number](matrix []T, width, pos P) (result []P) { func GetAdjacentTranslatePos[T any, P generic.SignedNumber](matrix []T, width, pos P) (result []P) {
size := P(len(matrix)) size := P(len(matrix))
currentRow := pos / width currentRow := pos / width
if up := pos - width; up >= 0 { if up := pos - width; up >= 0 {
@ -22,7 +22,7 @@ func GetAdjacentTranslatePos[T any, P generic.Number](matrix []T, width, pos P)
} }
// GetAdjacentTranslateCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置 // GetAdjacentTranslateCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
func GetAdjacentTranslateCoordinateXY[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) { func GetAdjacentTranslateCoordinateXY[T any, P generic.SignedNumber](matrix [][]T, x, y P) (result []Point[P]) {
width := P(len(matrix)) width := P(len(matrix))
height := P(len(matrix[0])) height := P(len(matrix[0]))
if up := y - 1; up >= 0 { if up := y - 1; up >= 0 {
@ -41,7 +41,7 @@ func GetAdjacentTranslateCoordinateXY[T any, P generic.Number](matrix [][]T, x,
} }
// GetAdjacentTranslateCoordinateYX 获取一个基于 y、x 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置 // GetAdjacentTranslateCoordinateYX 获取一个基于 y、x 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
func GetAdjacentTranslateCoordinateYX[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) { func GetAdjacentTranslateCoordinateYX[T any, P generic.SignedNumber](matrix [][]T, x, y P) (result []Point[P]) {
width := P(len(matrix[0])) width := P(len(matrix[0]))
height := P(len(matrix)) height := P(len(matrix))
if up := y - 1; up >= 0 { if up := y - 1; up >= 0 {
@ -60,7 +60,7 @@ func GetAdjacentTranslateCoordinateYX[T any, P generic.Number](matrix [][]T, x,
} }
// GetAdjacentDiagonalsPos 获取一个连续位置的矩阵中,特定位置相邻的对角线最多四个方向的位置 // GetAdjacentDiagonalsPos 获取一个连续位置的矩阵中,特定位置相邻的对角线最多四个方向的位置
func GetAdjacentDiagonalsPos[T any, P generic.Number](matrix []T, width, pos P) (result []P) { func GetAdjacentDiagonalsPos[T any, P generic.SignedNumber](matrix []T, width, pos P) (result []P) {
size := P(len(matrix)) size := P(len(matrix))
currentRow := pos / width currentRow := pos / width
if topLeft := pos - width - 1; topLeft >= 0 && currentRow-1 == (topLeft/width) { if topLeft := pos - width - 1; topLeft >= 0 && currentRow-1 == (topLeft/width) {
@ -79,7 +79,7 @@ func GetAdjacentDiagonalsPos[T any, P generic.Number](matrix []T, width, pos P)
} }
// GetAdjacentDiagonalsCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置 // GetAdjacentDiagonalsCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置
func GetAdjacentDiagonalsCoordinateXY[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) { func GetAdjacentDiagonalsCoordinateXY[T any, P generic.SignedNumber](matrix [][]T, x, y P) (result []Point[P]) {
width := P(len(matrix[0])) width := P(len(matrix[0]))
height := P(len(matrix)) height := P(len(matrix))
if nx, ny := x-1, y-1; nx >= 0 && ny >= 0 { if nx, ny := x-1, y-1; nx >= 0 && ny >= 0 {
@ -98,7 +98,7 @@ func GetAdjacentDiagonalsCoordinateXY[T any, P generic.Number](matrix [][]T, x,
} }
// GetAdjacentDiagonalsCoordinateYX 获取一个基于 tx 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置 // GetAdjacentDiagonalsCoordinateYX 获取一个基于 tx 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置
func GetAdjacentDiagonalsCoordinateYX[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) { func GetAdjacentDiagonalsCoordinateYX[T any, P generic.SignedNumber](matrix [][]T, x, y P) (result []Point[P]) {
width := P(len(matrix)) width := P(len(matrix))
height := P(len(matrix[0])) height := P(len(matrix[0]))
if nx, ny := x-1, y-1; nx >= 0 && ny >= 0 { if nx, ny := x-1, y-1; nx >= 0 && ny >= 0 {
@ -117,17 +117,17 @@ func GetAdjacentDiagonalsCoordinateYX[T any, P generic.Number](matrix [][]T, x,
} }
// GetAdjacentPos 获取一个连续位置的矩阵中,特定位置相邻的最多八个方向的位置 // GetAdjacentPos 获取一个连续位置的矩阵中,特定位置相邻的最多八个方向的位置
func GetAdjacentPos[T any, P generic.Number](matrix []T, width, pos P) (result []P) { func GetAdjacentPos[T any, P generic.SignedNumber](matrix []T, width, pos P) (result []P) {
return append(GetAdjacentTranslatePos(matrix, width, pos), GetAdjacentDiagonalsPos(matrix, width, pos)...) return append(GetAdjacentTranslatePos(matrix, width, pos), GetAdjacentDiagonalsPos(matrix, width, pos)...)
} }
// GetAdjacentCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的最多八个方向的位置 // GetAdjacentCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的最多八个方向的位置
func GetAdjacentCoordinateXY[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) { func GetAdjacentCoordinateXY[T any, P generic.SignedNumber](matrix [][]T, x, y P) (result []Point[P]) {
return append(GetAdjacentTranslateCoordinateXY(matrix, x, y), GetAdjacentDiagonalsCoordinateXY(matrix, x, y)...) return append(GetAdjacentTranslateCoordinateXY(matrix, x, y), GetAdjacentDiagonalsCoordinateXY(matrix, x, y)...)
} }
// GetAdjacentCoordinateYX 获取一个基于 yx 的二维矩阵中,特定位置相邻的最多八个方向的位置 // GetAdjacentCoordinateYX 获取一个基于 yx 的二维矩阵中,特定位置相邻的最多八个方向的位置
func GetAdjacentCoordinateYX[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) { func GetAdjacentCoordinateYX[T any, P generic.SignedNumber](matrix [][]T, x, y P) (result []Point[P]) {
return append(GetAdjacentTranslateCoordinateYX(matrix, x, y), GetAdjacentDiagonalsCoordinateYX(matrix, x, y)...) return append(GetAdjacentTranslateCoordinateYX(matrix, x, y), GetAdjacentDiagonalsCoordinateYX(matrix, x, y)...)
} }
@ -145,7 +145,7 @@ func CoordinateMatrixToPosMatrix[V any](matrix [][]V) (width int, posMatrix []V)
} }
// GetShapeCoverageAreaWithCoordinateArray 通过传入的一组坐标 xys 计算一个图形覆盖的矩形范围 // GetShapeCoverageAreaWithCoordinateArray 通过传入的一组坐标 xys 计算一个图形覆盖的矩形范围
func GetShapeCoverageAreaWithCoordinateArray[V generic.Number](xys ...Point[V]) (left, right, top, bottom V) { func GetShapeCoverageAreaWithCoordinateArray[V generic.SignedNumber](xys ...Point[V]) (left, right, top, bottom V) {
hasLeft, hasTop := false, false hasLeft, hasTop := false, false
for _, xy := range xys { for _, xy := range xys {
x, y := CoordinateArrayToCoordinate(xy) x, y := CoordinateArrayToCoordinate(xy)
@ -168,7 +168,7 @@ func GetShapeCoverageAreaWithCoordinateArray[V generic.Number](xys ...Point[V])
} }
// GetShapeCoverageAreaWithPos 通过传入的一组坐标 xys 计算一个图形覆盖的矩形范围 // GetShapeCoverageAreaWithPos 通过传入的一组坐标 xys 计算一个图形覆盖的矩形范围
func GetShapeCoverageAreaWithPos[V generic.Number](width V, positions ...V) (left, right, top, bottom V) { func GetShapeCoverageAreaWithPos[V generic.SignedNumber](width V, positions ...V) (left, right, top, bottom V) {
hasLeft, hasTop := false, false hasLeft, hasTop := false, false
for _, pos := range positions { for _, pos := range positions {
x, y := PosToCoordinate(width, pos) x, y := PosToCoordinate(width, pos)
@ -192,7 +192,7 @@ func GetShapeCoverageAreaWithPos[V generic.Number](width V, positions ...V) (lef
// CoverageAreaBoundless 将一个图形覆盖矩形范围设置为无边的 // CoverageAreaBoundless 将一个图形覆盖矩形范围设置为无边的
// - 无边化表示会将多余的部分进行裁剪,例如图形左边从 2 开始的时候,那么左边将会被裁剪到从 0 开始 // - 无边化表示会将多余的部分进行裁剪,例如图形左边从 2 开始的时候,那么左边将会被裁剪到从 0 开始
func CoverageAreaBoundless[V generic.Number](l, r, t, b V) (left, right, top, bottom V) { func CoverageAreaBoundless[V generic.SignedNumber](l, r, t, b V) (left, right, top, bottom V) {
differentX := 0 - l differentX := 0 - l
differentY := 0 - t differentY := 0 - t
left = l + differentX left = l + differentX
@ -205,7 +205,7 @@ func CoverageAreaBoundless[V generic.Number](l, r, t, b V) (left, right, top, bo
// GenerateShapeOnRectangle 生成一组二维坐标的形状 // GenerateShapeOnRectangle 生成一组二维坐标的形状
// - 这个形状将被在一个刚好能容纳形状的矩形中表示 // - 这个形状将被在一个刚好能容纳形状的矩形中表示
// - 为 true 的位置表示了形状的每一个点 // - 为 true 的位置表示了形状的每一个点
func GenerateShapeOnRectangle[V generic.Number](xys ...Point[V]) (result []PointCap[V, bool]) { func GenerateShapeOnRectangle[V generic.SignedNumber](xys ...Point[V]) (result []PointCap[V, bool]) {
left, r, top, b := GetShapeCoverageAreaWithCoordinateArray(xys...) left, r, top, b := GetShapeCoverageAreaWithCoordinateArray(xys...)
_, right, _, bottom := CoverageAreaBoundless(left, r, top, b) _, right, _, bottom := CoverageAreaBoundless(left, r, top, b)
w, h := right+1, bottom+1 w, h := right+1, bottom+1
@ -234,7 +234,7 @@ func GenerateShapeOnRectangle[V generic.Number](xys ...Point[V]) (result []Point
// GenerateShapeOnRectangleWithCoordinate 生成一组二维坐标的形状 // GenerateShapeOnRectangleWithCoordinate 生成一组二维坐标的形状
// - 这个形状将被在一个刚好能容纳形状的矩形中表示 // - 这个形状将被在一个刚好能容纳形状的矩形中表示
// - 为 true 的位置表示了形状的每一个点 // - 为 true 的位置表示了形状的每一个点
func GenerateShapeOnRectangleWithCoordinate[V generic.Number](xys ...Point[V]) (result [][]bool) { func GenerateShapeOnRectangleWithCoordinate[V generic.SignedNumber](xys ...Point[V]) (result [][]bool) {
left, r, top, b := GetShapeCoverageAreaWithCoordinateArray(xys...) left, r, top, b := GetShapeCoverageAreaWithCoordinateArray(xys...)
_, right, _, bottom := CoverageAreaBoundless(left, r, top, b) _, right, _, bottom := CoverageAreaBoundless(left, r, top, b)
w, h := right+1, bottom+1 w, h := right+1, bottom+1
@ -254,7 +254,7 @@ func GenerateShapeOnRectangleWithCoordinate[V generic.Number](xys ...Point[V]) (
// GetExpressibleRectangleBySize 获取一个宽高可表达的所有特定尺寸以上的矩形形状 // GetExpressibleRectangleBySize 获取一个宽高可表达的所有特定尺寸以上的矩形形状
// - 返回值表示了每一个矩形右下角的x,y位置左上角始终为0, 0 // - 返回值表示了每一个矩形右下角的x,y位置左上角始终为0, 0
// - 矩形尺寸由大到小 // - 矩形尺寸由大到小
func GetExpressibleRectangleBySize[V generic.Number](width, height, minWidth, minHeight V) (result []Point[V]) { func GetExpressibleRectangleBySize[V generic.SignedNumber](width, height, minWidth, minHeight V) (result []Point[V]) {
sourceWidth := width sourceWidth := width
if width == 0 || height == 0 { if width == 0 || height == 0 {
return nil return nil
@ -288,13 +288,13 @@ func GetExpressibleRectangleBySize[V generic.Number](width, height, minWidth, mi
// GetExpressibleRectangle 获取一个宽高可表达的所有矩形形状 // GetExpressibleRectangle 获取一个宽高可表达的所有矩形形状
// - 返回值表示了每一个矩形右下角的x,y位置左上角始终为0, 0 // - 返回值表示了每一个矩形右下角的x,y位置左上角始终为0, 0
// - 矩形尺寸由大到小 // - 矩形尺寸由大到小
func GetExpressibleRectangle[V generic.Number](width, height V) (result []Point[V]) { func GetExpressibleRectangle[V generic.SignedNumber](width, height V) (result []Point[V]) {
return GetExpressibleRectangleBySize(width, height, 1, 1) return GetExpressibleRectangleBySize(width, height, 1, 1)
} }
// GetRectangleFullPointsByXY 通过开始结束坐标获取一个矩形包含的所有点 // GetRectangleFullPointsByXY 通过开始结束坐标获取一个矩形包含的所有点
// - 例如 1,1 到 2,2 的矩形结果为 1,1 2,1 1,2 2,2 // - 例如 1,1 到 2,2 的矩形结果为 1,1 2,1 1,2 2,2
func GetRectangleFullPointsByXY[V generic.Number](startX, startY, endX, endY V) (result []Point[V]) { func GetRectangleFullPointsByXY[V generic.SignedNumber](startX, startY, endX, endY V) (result []Point[V]) {
for x := startX; x <= endX; x++ { for x := startX; x <= endX; x++ {
for y := startY; y <= endY; y++ { for y := startY; y <= endY; y++ {
result = append(result, NewPoint(x, y)) result = append(result, NewPoint(x, y))
@ -304,7 +304,7 @@ func GetRectangleFullPointsByXY[V generic.Number](startX, startY, endX, endY V)
} }
// GetRectangleFullPoints 获取一个矩形填充满后包含的所有点 // GetRectangleFullPoints 获取一个矩形填充满后包含的所有点
func GetRectangleFullPoints[V generic.Number](width, height V) (result []Point[V]) { func GetRectangleFullPoints[V generic.SignedNumber](width, height V) (result []Point[V]) {
for x := V(0); x < width; x++ { for x := V(0); x < width; x++ {
for y := V(0); y < height; y++ { for y := V(0); y < height; y++ {
result = append(result, NewPoint(x, y)) result = append(result, NewPoint(x, y))
@ -314,7 +314,7 @@ func GetRectangleFullPoints[V generic.Number](width, height V) (result []Point[V
} }
// GetRectangleFullPos 获取一个矩形填充满后包含的所有位置 // GetRectangleFullPos 获取一个矩形填充满后包含的所有位置
func GetRectangleFullPos[V generic.Number](width, height V) (result []V) { func GetRectangleFullPos[V generic.SignedNumber](width, height V) (result []V) {
size := int(width * height) size := int(width * height)
result = make([]V, 0, size) result = make([]V, 0, size)
for pos := 0; pos < size; pos++ { for pos := 0; pos < size; pos++ {

View File

@ -12,7 +12,7 @@ var (
) )
// Shape 通过多个点表示了一个形状 // Shape 通过多个点表示了一个形状
type Shape[V generic.Number] []Point[V] type Shape[V generic.SignedNumber] []Point[V]
// Points 获取这个形状的所有点 // Points 获取这个形状的所有点
func (slf Shape[V]) Points() []Point[V] { func (slf Shape[V]) Points() []Point[V] {