From 7ee7a674d7c5e17490520a0d852dcc5dbf688787 Mon Sep 17 00:00:00 2001 From: kercylan <61743331+kercylan98@users.noreply.github.com> Date: Sun, 18 Jun 2023 13:55:26 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E4=BF=AE=E6=94=B9=E8=8C=83?= =?UTF-8?q?=E5=9E=8B=E7=B1=BB=E5=9E=8B=E4=B8=BA=E5=B8=A6=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E5=8F=8Afloat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/generic/type.go | 4 ++++ utils/geometry/geometry.go | 14 +++++++------- utils/geometry/line.go | 12 ++++++------ utils/geometry/position.go | 34 ++++++++++++++++----------------- utils/geometry/rectangle.go | 38 ++++++++++++++++++------------------- utils/geometry/shape.go | 2 +- 6 files changed, 54 insertions(+), 50 deletions(-) diff --git a/utils/generic/type.go b/utils/generic/type.go index 7013117..84b50eb 100644 --- a/utils/generic/type.go +++ b/utils/generic/type.go @@ -8,6 +8,10 @@ type Number interface { Integer | Float } +type SignedNumber interface { + Signed | Float +} + type Integer interface { Signed | Unsigned } diff --git a/utils/geometry/geometry.go b/utils/geometry/geometry.go index df6422e..11bb7fd 100644 --- a/utils/geometry/geometry.go +++ b/utils/geometry/geometry.go @@ -37,7 +37,7 @@ func GetOppositionDirection(direction Direction) Direction { } // 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 { case DirectionUp: nx, ny = x, y-1 @@ -54,7 +54,7 @@ func GetDirectionNextWithCoordinate[V generic.Number](direction Direction, x, y } // 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() switch direction { case DirectionUp: @@ -72,7 +72,7 @@ func GetDirectionNextWithCoordinateArray[V generic.Number](direction Direction, // 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 { case DirectionUp: return pos - width @@ -88,7 +88,7 @@ func GetDirectionNextWithPos[V generic.Number](direction Direction, width, pos V } // 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 fortyFive = 45 var oneThirtyFive = 135 @@ -110,17 +110,17 @@ func CalcDirection[V generic.Number](x1, y1, x2, y2 V) Direction { } // 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))) } // 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) } // 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 dividend = 180.0 diff --git a/utils/geometry/line.go b/utils/geometry/line.go index c7161e2..b4c6a6f 100644 --- a/utils/geometry/line.go +++ b/utils/geometry/line.go @@ -5,12 +5,12 @@ import ( ) // 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) } // 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) x2, y2 := PosToCoordinate(width, pos2) x, y := PosToCoordinate(width, pos) @@ -18,7 +18,7 @@ func PointOnLineWithPos[V generic.Number](width, pos1, pos2, pos V) bool { } // 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() x2, y2 := point2.GetXY() x, y := point.GetXY() @@ -27,13 +27,13 @@ func PointOnLineWithCoordinateArray[V generic.Number](point1, point2, point Poin // 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) } // 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) x2, y2 := PosToCoordinate(width, pos2) x, y := PosToCoordinate(width, pos) @@ -42,7 +42,7 @@ func PointOnSegmentWithPos[V generic.Number](width, pos1, pos2, pos V) bool { // 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() x2, y2 := point2.GetXY() x, y := point.GetXY() diff --git a/utils/geometry/position.go b/utils/geometry/position.go index 7e89d91..0cde776 100644 --- a/utils/geometry/position.go +++ b/utils/geometry/position.go @@ -6,10 +6,10 @@ import ( ) // Point 表示了一个由 x、y 坐标组成的点 -type Point[V generic.Number] [2]V +type Point[V generic.SignedNumber] [2]V // 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} } @@ -54,14 +54,14 @@ func (slf Point[V]) Copy() Point[V] { } // 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]{ Point: NewPoint(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]{ Point: NewPoint(x, y), Data: data, @@ -69,7 +69,7 @@ func NewPointCapWithData[V generic.Number, D any](x, y V, data D) PointCap[V, D] } // PointCap 表示了一个由 x、y 坐标组成的点,这个点具有一个数据容量 -type PointCap[V generic.Number, D any] struct { +type PointCap[V generic.SignedNumber, D any] struct { Point[V] Data D } @@ -80,29 +80,29 @@ func (slf PointCap[V, D]) GetData() D { } // 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} } // CoordinateToPos 将坐标转换为二维数组的顺序位置坐标 // - 需要确保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 } // 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] } // CoordinateArrayToPos 将坐标转换为二维数组的顺序位置 // - 需要确保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]) } // 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))) y = pos / width @@ -110,28 +110,28 @@ func PosToCoordinate[V generic.Number](width, pos V) (x, y V) { } // 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} } // 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))) } // PosToCoordinateY 通过宽度将一个二维数组的顺序位置转换为Y坐标 -func PosToCoordinateY[V generic.Number](width, pos V) V { +func PosToCoordinateY[V generic.SignedNumber](width, pos V) V { return pos / width } // 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]) } // CoordinateArrayToPosWithMulti 将一组坐标转换为二维数组的顺序位置 // - 需要确保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)) for i := 0; i < len(xys); i++ { result[i] = CoordinateArrayToPos(width, xys[i]) @@ -140,7 +140,7 @@ func CoordinateArrayToPosWithMulti[V generic.Number](width V, xys ...Point[V]) [ } // 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)) for i := 0; i < len(positions); i++ { result[i] = PosToCoordinateArray(width, positions[i]) @@ -149,6 +149,6 @@ func PosToCoordinateArrayWithMulti[V generic.Number](width V, positions ...V) [] } // 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) } diff --git a/utils/geometry/rectangle.go b/utils/geometry/rectangle.go index a5fd4b7..58fc7fb 100644 --- a/utils/geometry/rectangle.go +++ b/utils/geometry/rectangle.go @@ -3,7 +3,7 @@ package geometry import "github.com/kercylan98/minotaur/utils/generic" // 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)) currentRow := pos / width 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 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置 -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)) height := P(len(matrix[0])) if up := y - 1; up >= 0 { @@ -41,7 +41,7 @@ func GetAdjacentTranslateCoordinateXY[T any, P generic.Number](matrix [][]T, 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])) height := P(len(matrix)) if up := y - 1; up >= 0 { @@ -60,7 +60,7 @@ func GetAdjacentTranslateCoordinateYX[T any, P generic.Number](matrix [][]T, x, } // 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)) currentRow := pos / 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 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置 -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])) height := P(len(matrix)) 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 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置 -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)) height := P(len(matrix[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 获取一个连续位置的矩阵中,特定位置相邻的最多八个方向的位置 -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)...) } // 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)...) } // 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)...) } @@ -145,7 +145,7 @@ func CoordinateMatrixToPosMatrix[V any](matrix [][]V) (width int, posMatrix []V) } // 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 for _, xy := range xys { x, y := CoordinateArrayToCoordinate(xy) @@ -168,7 +168,7 @@ func GetShapeCoverageAreaWithCoordinateArray[V generic.Number](xys ...Point[V]) } // 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 for _, pos := range positions { x, y := PosToCoordinate(width, pos) @@ -192,7 +192,7 @@ func GetShapeCoverageAreaWithPos[V generic.Number](width V, positions ...V) (lef // CoverageAreaBoundless 将一个图形覆盖矩形范围设置为无边的 // - 无边化表示会将多余的部分进行裁剪,例如图形左边从 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 differentY := 0 - t left = l + differentX @@ -205,7 +205,7 @@ func CoverageAreaBoundless[V generic.Number](l, r, t, b V) (left, right, top, bo // GenerateShapeOnRectangle 生成一组二维坐标的形状 // - 这个形状将被在一个刚好能容纳形状的矩形中表示 // - 为 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...) _, right, _, bottom := CoverageAreaBoundless(left, r, top, b) w, h := right+1, bottom+1 @@ -234,7 +234,7 @@ func GenerateShapeOnRectangle[V generic.Number](xys ...Point[V]) (result []Point // GenerateShapeOnRectangleWithCoordinate 生成一组二维坐标的形状 // - 这个形状将被在一个刚好能容纳形状的矩形中表示 // - 为 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...) _, right, _, bottom := CoverageAreaBoundless(left, r, top, b) w, h := right+1, bottom+1 @@ -254,7 +254,7 @@ func GenerateShapeOnRectangleWithCoordinate[V generic.Number](xys ...Point[V]) ( // GetExpressibleRectangleBySize 获取一个宽高可表达的所有特定尺寸以上的矩形形状 // - 返回值表示了每一个矩形右下角的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 if width == 0 || height == 0 { return nil @@ -288,13 +288,13 @@ func GetExpressibleRectangleBySize[V generic.Number](width, height, minWidth, mi // GetExpressibleRectangle 获取一个宽高可表达的所有矩形形状 // - 返回值表示了每一个矩形右下角的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) } // GetRectangleFullPointsByXY 通过开始结束坐标获取一个矩形包含的所有点 // - 例如 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 y := startY; y <= endY; y++ { result = append(result, NewPoint(x, y)) @@ -304,7 +304,7 @@ func GetRectangleFullPointsByXY[V generic.Number](startX, startY, endX, endY V) } // 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 y := V(0); y < height; y++ { result = append(result, NewPoint(x, y)) @@ -314,7 +314,7 @@ func GetRectangleFullPoints[V generic.Number](width, height V) (result []Point[V } // 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) result = make([]V, 0, size) for pos := 0; pos < size; pos++ { diff --git a/utils/geometry/shape.go b/utils/geometry/shape.go index 4f6e512..6af79aa 100644 --- a/utils/geometry/shape.go +++ b/utils/geometry/shape.go @@ -12,7 +12,7 @@ var ( ) // Shape 通过多个点表示了一个形状 -type Shape[V generic.Number] []Point[V] +type Shape[V generic.SignedNumber] []Point[V] // Points 获取这个形状的所有点 func (slf Shape[V]) Points() []Point[V] {