🎨 将g2d部分函数抽离到集合geometry包中,优化结构
This commit is contained in:
parent
eb1def1bf4
commit
9849562a0f
|
@ -1,7 +1,7 @@
|
||||||
package dp
|
package dp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kercylan98/minotaur/utils/g2d"
|
"github.com/kercylan98/minotaur/utils/geometry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDistributionPattern 构建一个分布图实例
|
// NewDistributionPattern 构建一个分布图实例
|
||||||
|
@ -43,7 +43,7 @@ func (slf *DistributionPattern[Item]) HasLink(pos int) bool {
|
||||||
// - 通过该函数加载的分布图使用的矩阵是复制后的矩阵,因此无法直接通过刷新(Refresh)来更新分布关系
|
// - 通过该函数加载的分布图使用的矩阵是复制后的矩阵,因此无法直接通过刷新(Refresh)来更新分布关系
|
||||||
// - 需要通过直接刷新的方式请使用 LoadMatrixWithPos
|
// - 需要通过直接刷新的方式请使用 LoadMatrixWithPos
|
||||||
func (slf *DistributionPattern[Item]) LoadMatrix(matrix [][]Item) {
|
func (slf *DistributionPattern[Item]) LoadMatrix(matrix [][]Item) {
|
||||||
slf.LoadMatrixWithPos(g2d.MatrixToPosMatrix(matrix))
|
slf.LoadMatrixWithPos(geometry.CoordinateMatrixToPosMatrix(matrix))
|
||||||
slf.usePos = false
|
slf.usePos = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ func (slf *DistributionPattern[Item]) buildRelationships(pos int, item Item) {
|
||||||
slf.links[pos] = links
|
slf.links[pos] = links
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tp := range g2d.GetAdjacentTranslatePos(slf.matrix, slf.width, pos) {
|
for _, tp := range geometry.GetAdjacentTranslatePos(slf.matrix, slf.width, pos) {
|
||||||
target := slf.matrix[tp]
|
target := slf.matrix[tp]
|
||||||
if _, exist := links[tp]; exist || !slf.sameKindVerifyHandle(item, target) {
|
if _, exist := links[tp]; exist || !slf.sameKindVerifyHandle(item, target) {
|
||||||
continue
|
continue
|
||||||
|
|
140
utils/g2d/g2d.go
140
utils/g2d/g2d.go
|
@ -1,140 +0,0 @@
|
||||||
package g2d
|
|
||||||
|
|
||||||
import "github.com/kercylan98/minotaur/utils/generic"
|
|
||||||
|
|
||||||
// CoordinateToCoordinateArray 将坐标转换为x、y的坐标数组
|
|
||||||
func CoordinateToCoordinateArray(x, y int) [2]int {
|
|
||||||
return [2]int{x, y}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoordinateArrayToCoordinate 将坐标数组转换为x和y坐标
|
|
||||||
func CoordinateArrayToCoordinate(position [2]int) (x, y int) {
|
|
||||||
return position[0], position[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoordinateArrayClone 克隆一个坐标数组
|
|
||||||
func CoordinateArrayClone(position [2]int) [2]int {
|
|
||||||
return [2]int{position[0], position[1]}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAdjacentCoordinates 获取一个矩阵中,特定位置相邻的最多四个方向的坐标
|
|
||||||
func GetAdjacentCoordinates[T any](matrix [][]T, x, y int) (result [][2]int) {
|
|
||||||
width, height := len(matrix), len(matrix[0])
|
|
||||||
if tx := x - 1; tx >= 0 {
|
|
||||||
result = append(result, CoordinateToCoordinateArray(tx, y))
|
|
||||||
}
|
|
||||||
if tx := x + 1; tx < width {
|
|
||||||
result = append(result, CoordinateToCoordinateArray(tx, y))
|
|
||||||
}
|
|
||||||
if ty := y - 1; ty >= 0 {
|
|
||||||
result = append(result, CoordinateToCoordinateArray(x, ty))
|
|
||||||
}
|
|
||||||
if ty := y + 1; ty < height {
|
|
||||||
result = append(result, CoordinateToCoordinateArray(x, ty))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAdjacentTranslatePos 获取一个连续位置的矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
|
|
||||||
func GetAdjacentTranslatePos[T any](matrix []T, width, pos int) (result []int) {
|
|
||||||
size := len(matrix)
|
|
||||||
currentRow := pos / width
|
|
||||||
if up := pos - width; up >= 0 {
|
|
||||||
result = append(result, up)
|
|
||||||
}
|
|
||||||
if down := pos + width; down < size {
|
|
||||||
result = append(result, down)
|
|
||||||
}
|
|
||||||
if left := pos - 1; left >= 0 && currentRow == (left/width) {
|
|
||||||
result = append(result, left)
|
|
||||||
}
|
|
||||||
if right := pos + 1; right < size && currentRow == (right/width) {
|
|
||||||
result = append(result, right)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAdjacentDiagonalsPos 获取一个连续位置的矩阵中,特定位置相邻的对角线最多四个方向的位置
|
|
||||||
func GetAdjacentDiagonalsPos[T any](matrix []T, width, pos int) (result []int) {
|
|
||||||
size := len(matrix)
|
|
||||||
currentRow := pos / width
|
|
||||||
if topLeft := pos - width - 1; topLeft >= 0 && currentRow-1 == (topLeft/width) {
|
|
||||||
result = append(result, topLeft)
|
|
||||||
}
|
|
||||||
if topRight := pos - width + 1; topRight >= 0 && currentRow-1 == (topRight/width) {
|
|
||||||
result = append(result, topRight)
|
|
||||||
}
|
|
||||||
if bottomLeft := pos + width - 1; bottomLeft < size && currentRow+1 == (bottomLeft/width) {
|
|
||||||
result = append(result, bottomLeft)
|
|
||||||
}
|
|
||||||
if bottomRight := pos + width + 1; bottomRight < size && currentRow+1 == (bottomRight/width) {
|
|
||||||
result = append(result, bottomRight)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAdjacentPos 获取一个连续位置的矩阵中,特定位置相邻的最多八个方向的位置
|
|
||||||
func GetAdjacentPos[T any](matrix []T, width, pos int) (result []int) {
|
|
||||||
return append(GetAdjacentTranslatePos(matrix, width, pos), GetAdjacentDiagonalsPos(matrix, width, pos)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoordinateToPos 将坐标转换为二维数组的顺序位置坐标
|
|
||||||
// - 需要确保x的取值范围必须小于width,或者将会得到不正确的值
|
|
||||||
func CoordinateToPos(width, x, y int) int {
|
|
||||||
return y*width + x
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoordinateArrayToPos 将坐标转换为二维数组的顺序位置
|
|
||||||
// - 需要确保x的取值范围必须小于width,或者将会得到不正确的值
|
|
||||||
func CoordinateArrayToPos(width int, xy [2]int) int {
|
|
||||||
return CoordinateToPos(width, xy[0], xy[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoordinateArrayToPosWithMulti 将一组坐标转换为二维数组的顺序位置
|
|
||||||
// - 需要确保x的取值范围必须小于width,或者将会得到不正确的值
|
|
||||||
func CoordinateArrayToPosWithMulti(width int, xys ...[2]int) []int {
|
|
||||||
var result = make([]int, len(xys), len(xys))
|
|
||||||
for i := 0; i < len(xys); i++ {
|
|
||||||
result[i] = CoordinateArrayToPos(width, xys[i])
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// PosToCoordinate 通过宽度将一个二维数组的顺序位置转换为xy坐标
|
|
||||||
func PosToCoordinate(width, pos int) (x, y int) {
|
|
||||||
x = pos % width
|
|
||||||
y = pos / width
|
|
||||||
return x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
// PosToCoordinateX 通过宽度将一个二维数组的顺序位置转换为X坐标
|
|
||||||
func PosToCoordinateX(width, pos int) int {
|
|
||||||
return pos % width
|
|
||||||
}
|
|
||||||
|
|
||||||
// PosToCoordinateY 通过宽度将一个二维数组的顺序位置转换为Y坐标
|
|
||||||
func PosToCoordinateY(width, pos int) int {
|
|
||||||
return pos / width
|
|
||||||
}
|
|
||||||
|
|
||||||
// MatrixToPosMatrix 将二维矩阵转换为顺序的二维矩阵
|
|
||||||
func MatrixToPosMatrix[V any](matrix [][]V) (width int, posMatrix []V) {
|
|
||||||
width = len(matrix)
|
|
||||||
height := len(matrix[0])
|
|
||||||
posMatrix = make([]V, width*height)
|
|
||||||
for x := 0; x < width; x++ {
|
|
||||||
for y := 0; y < height; y++ {
|
|
||||||
posMatrix[CoordinateToPos(width, x, y)] = matrix[x][y]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// PointOnLine 接受六个参数 top、bottom、left、right 和 x、y,分别表示一个矩形位置尺寸和一个点的横纵坐标,判断这个点是否在一条线段上。
|
|
||||||
// - 首先计算点 (x, y) 与线段起点 (left, top) 之间的斜率即 (x - left) / (y - top)。
|
|
||||||
// - 然后计算线段起点 (left, top) 与线段终点 (right, bottom) 之间的斜率,即 (right - left) / (bottom - top)。
|
|
||||||
// - 如果这两个斜率等,那么点 (x, y) 就在这条线段上。为了避免除法可能导致的浮点数误差,我们可以将两个斜率的计算转换为乘法形式,即比较 (x - left) * (bottom - top) 是否等于 (right - left) * y - top)。
|
|
||||||
// - 如果上述等式成立,说明点 (x, y) 在线段上,函数返回 true;否则,返回 false。
|
|
||||||
func PointOnLine[V generic.Number](top, bottom, left, right, x, y V) bool {
|
|
||||||
return (x-left)*(bottom-top) == (right-left)*(y-top)
|
|
||||||
}
|
|
|
@ -2,15 +2,16 @@ package g2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/kercylan98/minotaur/utils/geometry"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPositionIntToXY(t *testing.T) {
|
func TestPositionIntToXY(t *testing.T) {
|
||||||
pos := CoordinateToPos(9, 7, 8)
|
pos := geometry.CoordinateToPos(9, 7, 8)
|
||||||
fmt.Println(pos)
|
fmt.Println(pos)
|
||||||
fmt.Println(PosToCoordinate(9, pos))
|
fmt.Println(geometry.PosToCoordinate(9, pos))
|
||||||
|
|
||||||
fmt.Println(CoordinateToPos(65000, 61411, 158266))
|
fmt.Println(geometry.CoordinateToPos(65000, 61411, 158266))
|
||||||
fmt.Println(PosToCoordinate(65000, 10287351411))
|
fmt.Println(geometry.PosToCoordinate(65000, 10287351411))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package matrix
|
package matrix
|
||||||
|
|
||||||
import "github.com/kercylan98/minotaur/utils/g2d"
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/geometry"
|
||||||
|
)
|
||||||
|
|
||||||
// NewMatrix 生成特定宽高的二维矩阵
|
// NewMatrix 生成特定宽高的二维矩阵
|
||||||
// - 虽然提供了通过x、y坐标的操作函数,但是建议无论如何使用pos进行处理
|
// - 虽然提供了通过x、y坐标的操作函数,但是建议无论如何使用pos进行处理
|
||||||
|
@ -41,7 +43,7 @@ func (slf *Matrix[T]) GetMatrix() [][]T {
|
||||||
for x := 0; x < slf.w; x++ {
|
for x := 0; x < slf.w; x++ {
|
||||||
ys := make([]T, slf.h)
|
ys := make([]T, slf.h)
|
||||||
for y := 0; y < slf.h; y++ {
|
for y := 0; y < slf.h; y++ {
|
||||||
ys[y] = slf.m[g2d.CoordinateToPos(slf.w, x, y)]
|
ys[y] = slf.m[geometry.CoordinateToPos(slf.w, x, y)]
|
||||||
}
|
}
|
||||||
result[x] = ys
|
result[x] = ys
|
||||||
}
|
}
|
||||||
|
@ -55,7 +57,7 @@ func (slf *Matrix[T]) GetMatrixWithPos() []T {
|
||||||
|
|
||||||
// Get 获取特定坐标的内容
|
// Get 获取特定坐标的内容
|
||||||
func (slf *Matrix[T]) Get(x, y int) (value T) {
|
func (slf *Matrix[T]) Get(x, y int) (value T) {
|
||||||
return slf.m[g2d.CoordinateToPos(slf.w, x, y)]
|
return slf.m[geometry.CoordinateToPos(slf.w, x, y)]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWithPos 获取特定坐标的内容
|
// GetWithPos 获取特定坐标的内容
|
||||||
|
@ -65,7 +67,7 @@ func (slf *Matrix[T]) GetWithPos(pos int) (value T) {
|
||||||
|
|
||||||
// Set 设置特定坐标的内容
|
// Set 设置特定坐标的内容
|
||||||
func (slf *Matrix[T]) Set(x, y int, data T) {
|
func (slf *Matrix[T]) Set(x, y int, data T) {
|
||||||
slf.m[g2d.CoordinateToPos(slf.w, x, y)] = data
|
slf.m[geometry.CoordinateToPos(slf.w, x, y)] = data
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWithPos 设置特定坐标的内容
|
// SetWithPos 设置特定坐标的内容
|
||||||
|
@ -76,7 +78,7 @@ func (slf *Matrix[T]) SetWithPos(pos int, data T) {
|
||||||
// Swap 交换两个位置的内容
|
// Swap 交换两个位置的内容
|
||||||
func (slf *Matrix[T]) Swap(x1, y1, x2, y2 int) {
|
func (slf *Matrix[T]) Swap(x1, y1, x2, y2 int) {
|
||||||
a, b := slf.Get(x1, y1), slf.Get(x2, y2)
|
a, b := slf.Get(x1, y1), slf.Get(x2, y2)
|
||||||
slf.m[g2d.CoordinateToPos(slf.w, x1, y1)], slf.m[g2d.CoordinateToPos(slf.w, x2, y2)] = b, a
|
slf.m[geometry.CoordinateToPos(slf.w, x1, y1)], slf.m[geometry.CoordinateToPos(slf.w, x2, y2)] = b, a
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwapWithPos 交换两个位置的内容
|
// SwapWithPos 交换两个位置的内容
|
||||||
|
@ -87,8 +89,8 @@ func (slf *Matrix[T]) SwapWithPos(pos1, pos2 int) {
|
||||||
|
|
||||||
// TrySwap 尝试交换两个位置的内容,交换后不满足表达式时进行撤销
|
// TrySwap 尝试交换两个位置的内容,交换后不满足表达式时进行撤销
|
||||||
func (slf *Matrix[T]) TrySwap(x1, y1, x2, y2 int, expressionHandle func(matrix *Matrix[T]) bool) {
|
func (slf *Matrix[T]) TrySwap(x1, y1, x2, y2 int, expressionHandle func(matrix *Matrix[T]) bool) {
|
||||||
pos1 := g2d.CoordinateToPos(slf.w, x1, y1)
|
pos1 := geometry.CoordinateToPos(slf.w, x1, y1)
|
||||||
pos2 := g2d.CoordinateToPos(slf.w, x2, y2)
|
pos2 := geometry.CoordinateToPos(slf.w, x2, y2)
|
||||||
a, b := slf.Get(x1, y1), slf.Get(x2, y2)
|
a, b := slf.Get(x1, y1), slf.Get(x2, y2)
|
||||||
slf.m[pos1], slf.m[pos2] = b, a
|
slf.m[pos1], slf.m[pos2] = b, a
|
||||||
if !expressionHandle(slf) {
|
if !expressionHandle(slf) {
|
||||||
|
@ -109,7 +111,7 @@ func (slf *Matrix[T]) TrySwapWithPos(pos1, pos2 int, expressionHandle func(matri
|
||||||
func (slf *Matrix[T]) FillFull(generateHandle func(x, y int) T) {
|
func (slf *Matrix[T]) FillFull(generateHandle func(x, y int) T) {
|
||||||
for x := 0; x < slf.w; x++ {
|
for x := 0; x < slf.w; x++ {
|
||||||
for y := 0; y < slf.h; y++ {
|
for y := 0; y < slf.h; y++ {
|
||||||
slf.m[g2d.CoordinateToPos(slf.w, x, y)] = generateHandle(x, y)
|
slf.m[geometry.CoordinateToPos(slf.w, x, y)] = generateHandle(x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package path
|
package path
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kercylan98/minotaur/utils/g2d"
|
"github.com/kercylan98/minotaur/utils/geometry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewLandform(pos int, features ...*LandformFeature) *Landform {
|
func NewLandform(pos int, features ...*LandformFeature) *Landform {
|
||||||
|
@ -29,7 +29,7 @@ type Landform struct {
|
||||||
// GetCoordinate 获取这个路径地貌指向的 x 和 y 坐标
|
// GetCoordinate 获取这个路径地貌指向的 x 和 y 坐标
|
||||||
// - 建议通过 GetPos 来进行获取,这样可以避免一次转换
|
// - 建议通过 GetPos 来进行获取,这样可以避免一次转换
|
||||||
func (slf *Landform) GetCoordinate() (x, y int) {
|
func (slf *Landform) GetCoordinate() (x, y int) {
|
||||||
return g2d.PosToCoordinate(slf.width, slf.pos)
|
return geometry.PosToCoordinate(slf.width, slf.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPos 获取这个路径地貌指向的 pos 位置
|
// GetPos 获取这个路径地貌指向的 pos 位置
|
||||||
|
|
|
@ -2,7 +2,7 @@ package path
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"github.com/kercylan98/minotaur/utils/g2d"
|
"github.com/kercylan98/minotaur/utils/geometry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewTerrain 返回一个大小为 width 和 height 的新的路径覆盖信息,landformWidth 和 landformHeight 将对每
|
// NewTerrain 返回一个大小为 width 和 height 的新的路径覆盖信息,landformWidth 和 landformHeight 将对每
|
||||||
|
@ -49,7 +49,7 @@ type Terrain struct {
|
||||||
// Get 返回 x 和 y 指向的地貌信息
|
// Get 返回 x 和 y 指向的地貌信息
|
||||||
// - 通常更建议使用 GetWithPos 进行获取,因为这样可以减少一次转换
|
// - 通常更建议使用 GetWithPos 进行获取,因为这样可以减少一次转换
|
||||||
func (slf *Terrain) Get(x, y int) *Landform {
|
func (slf *Terrain) Get(x, y int) *Landform {
|
||||||
return slf.matrix[g2d.CoordinateToPos(slf.width, x, y)]
|
return slf.matrix[geometry.CoordinateToPos(slf.width, x, y)]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWithPos 返回 pos 指向的地貌信息
|
// GetWithPos 返回 pos 指向的地貌信息
|
||||||
|
@ -105,7 +105,7 @@ func (slf *Terrain) GetPath(startPos, endPos int, diagonals, wallsBlockDiagonals
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, adjacent := range g2d.GetAdjacentTranslatePos(slf.matrix, slf.width, node.landform.pos) {
|
for _, adjacent := range geometry.GetAdjacentTranslatePos(slf.matrix, slf.width, node.landform.pos) {
|
||||||
landform := slf.GetWithPos(adjacent)
|
landform := slf.GetWithPos(adjacent)
|
||||||
n := &Node{landform: landform, parent: node, cost: landform.GetTotalCost() + node.cost}
|
n := &Node{landform: landform, parent: node, cost: landform.GetTotalCost() + node.cost}
|
||||||
if _, exist := checkedLandforms[adjacent]; n.landform.Walkable() && !exist {
|
if _, exist := checkedLandforms[adjacent]; n.landform.Walkable() && !exist {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package g2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kercylan98/minotaur/utils/g2d/shape"
|
"github.com/kercylan98/minotaur/utils/g2d/shape"
|
||||||
|
"github.com/kercylan98/minotaur/utils/geometry"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -149,7 +150,7 @@ func SearchNotRepeatCross(xys ...[2]int) (result [][][2]int) {
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -204,7 +205,7 @@ func SearchNotRepeatCross(xys ...[2]int) (result [][][2]int) {
|
||||||
for _, points := range result {
|
for _, points := range result {
|
||||||
var match = true
|
var match = true
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
x, y := CoordinateArrayToCoordinate(point)
|
x, y := geometry.CoordinateArrayToCoordinate(point)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
if record[x][y] {
|
if record[x][y] {
|
||||||
|
@ -235,7 +236,7 @@ func SearchContainCross(xys ...[2]int) bool {
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -303,7 +304,7 @@ func SearchNotRepeatStraightLine(minLength int, xys ...[2]int) (result [][][2]in
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -362,7 +363,7 @@ func SearchNotRepeatStraightLine(minLength int, xys ...[2]int) (result [][][2]in
|
||||||
for _, points := range result {
|
for _, points := range result {
|
||||||
var match = true
|
var match = true
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
x, y := CoordinateArrayToCoordinate(point)
|
x, y := geometry.CoordinateArrayToCoordinate(point)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
if record[x][y] {
|
if record[x][y] {
|
||||||
|
@ -396,7 +397,7 @@ func SearchContainStraightLine(minLength int, xys ...[2]int) bool {
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -467,7 +468,7 @@ func SearchNotRepeatT(minLength int, xys ...[2]int) (result [][][2]int) {
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -513,7 +514,7 @@ func SearchNotRepeatT(minLength int, xys ...[2]int) (result [][][2]int) {
|
||||||
for _, points := range result {
|
for _, points := range result {
|
||||||
var match = true
|
var match = true
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
x, y := CoordinateArrayToCoordinate(point)
|
x, y := geometry.CoordinateArrayToCoordinate(point)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
if record[x][y] {
|
if record[x][y] {
|
||||||
|
@ -547,7 +548,7 @@ func SearchContainT(minLength int, xys ...[2]int) bool {
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -605,7 +606,7 @@ func SearchNotRepeatRightAngle(minLength int, xys ...[2]int) (result [][][2]int)
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -665,7 +666,7 @@ func SearchNotRepeatRightAngle(minLength int, xys ...[2]int) (result [][][2]int)
|
||||||
for _, points := range result {
|
for _, points := range result {
|
||||||
var match = true
|
var match = true
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
x, y := CoordinateArrayToCoordinate(point)
|
x, y := geometry.CoordinateArrayToCoordinate(point)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
if record[x][y] {
|
if record[x][y] {
|
||||||
|
@ -699,7 +700,7 @@ func SearchContainRightAngle(minLength int, xys ...[2]int) bool {
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
var points [][2]int
|
var points [][2]int
|
||||||
var find = map[int]bool{}
|
var find = map[int]bool{}
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
x = x + (0 - left)
|
x = x + (0 - left)
|
||||||
y = y + (0 - top)
|
y = y + (0 - top)
|
||||||
// 搜索四个方向
|
// 搜索四个方向
|
||||||
|
@ -783,7 +784,7 @@ func SearchNotRepeatFullRectangle(minWidth, minHeight int, xys ...[2]int) (resul
|
||||||
points := GetRectangleFullPoints(s[0]+1, s[1]+1)
|
points := GetRectangleFullPoints(s[0]+1, s[1]+1)
|
||||||
find := 0
|
find := 0
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
px, py := CoordinateArrayToCoordinate(point)
|
px, py := geometry.CoordinateArrayToCoordinate(point)
|
||||||
ox, oy := px+x, py+y
|
ox, oy := px+x, py+y
|
||||||
if record[ox][oy] || !rectangleShape[ox][oy] {
|
if record[ox][oy] || !rectangleShape[ox][oy] {
|
||||||
find = 0
|
find = 0
|
||||||
|
@ -793,7 +794,7 @@ func SearchNotRepeatFullRectangle(minWidth, minHeight int, xys ...[2]int) (resul
|
||||||
}
|
}
|
||||||
if find == len(points) {
|
if find == len(points) {
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
px, py := CoordinateArrayToCoordinate(point)
|
px, py := geometry.CoordinateArrayToCoordinate(point)
|
||||||
record[px+x][py+y] = true
|
record[px+x][py+y] = true
|
||||||
}
|
}
|
||||||
result = append(result, [2][2]int{
|
result = append(result, [2][2]int{
|
||||||
|
@ -834,7 +835,7 @@ func SearchContainFullRectangle(minWidth, minHeight int, xys ...[2]int) bool {
|
||||||
points := GetRectangleFullPoints(s[0]+1, s[1]+1)
|
points := GetRectangleFullPoints(s[0]+1, s[1]+1)
|
||||||
find := 0
|
find := 0
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
px, py := CoordinateArrayToCoordinate(point)
|
px, py := geometry.CoordinateArrayToCoordinate(point)
|
||||||
ox, oy := px+x, py+y
|
ox, oy := px+x, py+y
|
||||||
if record[ox][oy] || !rectangleShape[ox][oy] {
|
if record[ox][oy] || !rectangleShape[ox][oy] {
|
||||||
find = 0
|
find = 0
|
||||||
|
@ -844,7 +845,7 @@ func SearchContainFullRectangle(minWidth, minHeight int, xys ...[2]int) bool {
|
||||||
}
|
}
|
||||||
if find == len(points) {
|
if find == len(points) {
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
px, py := CoordinateArrayToCoordinate(point)
|
px, py := geometry.CoordinateArrayToCoordinate(point)
|
||||||
record[px+x][py+y] = true
|
record[px+x][py+y] = true
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -931,7 +932,7 @@ func GenerateShape(xys ...[2]int) [][]bool {
|
||||||
m[x] = make([]bool, h)
|
m[x] = make([]bool, h)
|
||||||
}
|
}
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
m[x-(r-right)][y-(b-bottom)] = true
|
m[x-(r-right)][y-(b-bottom)] = true
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
|
@ -953,7 +954,7 @@ func CoverageAreaBoundless(l, r, t, b int) (left, right, top, bottom int) {
|
||||||
func GetShapeCoverageArea(xys ...[2]int) (left, right, top, bottom int) {
|
func GetShapeCoverageArea(xys ...[2]int) (left, right, top, bottom int) {
|
||||||
left, top = -1, -1
|
left, top = -1, -1
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
x, y := CoordinateArrayToCoordinate(xy)
|
x, y := geometry.CoordinateArrayToCoordinate(xy)
|
||||||
if x < left || left == -1 {
|
if x < left || left == -1 {
|
||||||
left = x
|
left = x
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package geometry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PointOnLineWithCoordinate 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
|
||||||
|
func PointOnLineWithCoordinate[V generic.Number](x1, y1, x2, y2, x, y V) bool {
|
||||||
|
return (x-x1)*(y2-y1) == (x2-x1)*(y-y1)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//func PointOnLineWithPos[V generic.Number](width, pos1, pos2, pos V) bool {
|
||||||
|
// x1, y1 := PosToCoordinate(width, pos1)
|
||||||
|
// x2, y2 := PosToCoordinate(width, pos2)
|
||||||
|
// return (x-x1)*(y2-y1) == (x2-x1)*(y-y1)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// PointOnSegment 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
|
||||||
|
//// - 与 PointOnLine 不同的是, PointOnSegment 中会判断线段及点的位置是否正确
|
||||||
|
//func PointOnSegment[V generic.Number](x1, y1, x2, y2, x, y V) bool {
|
||||||
|
// return x >= x1 && x <= x2 && y >= y1 && y <= y2 && PointOnLine(x1, y1, x2, y2, x, y)
|
||||||
|
//}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package geometry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/generic"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Point 表示了一个由 x、y 坐标组成的点
|
||||||
|
type Point[V generic.Number] [2]V
|
||||||
|
|
||||||
|
// NewPoint 创建一个由 x、y 坐标组成的点
|
||||||
|
func NewPoint[V generic.Number](x, y V) Point[V] {
|
||||||
|
return Point[V]{x, y}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetX 返回该点的 x 坐标
|
||||||
|
func (slf Point[V]) GetX() V {
|
||||||
|
return slf[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetY 返回该点的 y 坐标
|
||||||
|
func (slf Point[V]) GetY() V {
|
||||||
|
return slf[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetXY 返回该点的 x、y 坐标
|
||||||
|
func (slf Point[V]) GetXY() (x, y V) {
|
||||||
|
return slf[0], slf[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPos 返回该点位于特定宽度的二维数组的顺序位置
|
||||||
|
func (slf Point[V]) GetPos(width V) V {
|
||||||
|
return CoordinateArrayToPos(width, slf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy 复制一个点位置
|
||||||
|
func (slf Point[V]) Copy() Point[V] {
|
||||||
|
return CoordinateArrayCopy(slf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoordinateToCoordinateArray 将坐标转换为x、y的坐标数组
|
||||||
|
func CoordinateToCoordinateArray[V generic.Number](x, y V) Point[V] {
|
||||||
|
return [2]V{x, y}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoordinateToPos 将坐标转换为二维数组的顺序位置坐标
|
||||||
|
// - 需要确保x的取值范围必须小于width,或者将会得到不正确的值
|
||||||
|
func CoordinateToPos[V generic.Number](width, x, y V) V {
|
||||||
|
return y*width + x
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoordinateArrayToCoordinate 将坐标数组转换为x和y坐标
|
||||||
|
func CoordinateArrayToCoordinate[V generic.Number](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 {
|
||||||
|
return CoordinateToPos(width, xy[0], xy[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// PosToCoordinate 通过宽度将一个二维数组的顺序位置转换为xy坐标
|
||||||
|
func PosToCoordinate[V generic.Number](width, pos V) (x, y V) {
|
||||||
|
|
||||||
|
x = V(math.Mod(float64(pos), float64(width)))
|
||||||
|
y = pos / width
|
||||||
|
return x, y
|
||||||
|
}
|
||||||
|
|
||||||
|
// PosToCoordinateArray 通过宽度将一个二维数组的顺序位置转换为x、y的坐标数组
|
||||||
|
func PosToCoordinateArray[V generic.Number](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 {
|
||||||
|
return V(math.Mod(float64(pos), float64(width)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PosToCoordinateY 通过宽度将一个二维数组的顺序位置转换为Y坐标
|
||||||
|
func PosToCoordinateY[V generic.Number](width, pos V) V {
|
||||||
|
return pos / width
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoordinateArrayCopy 复制一个坐标数组
|
||||||
|
func CoordinateArrayCopy[V generic.Number](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 {
|
||||||
|
var result = make([]V, len(xys), len(xys))
|
||||||
|
for i := 0; i < len(xys); i++ {
|
||||||
|
result[i] = CoordinateArrayToPos(width, xys[i])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// PosToCoordinateArrayWithMulti 将一组二维数组的顺序位置转换为一组数组坐标
|
||||||
|
func PosToCoordinateArrayWithMulti[V generic.Number](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])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package geometry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewPoint(t *testing.T) {
|
||||||
|
p := [2]int{1, 1}
|
||||||
|
fmt.Println(CoordinateArrayToPos(9, p))
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
package geometry
|
||||||
|
|
||||||
|
import "github.com/kercylan98/minotaur/utils/generic"
|
||||||
|
|
||||||
|
// GetAdjacentTranslatePos 获取一个连续位置的矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
|
||||||
|
func GetAdjacentTranslatePos[T any, P generic.Number](matrix []T, width, pos P) (result []P) {
|
||||||
|
size := P(len(matrix))
|
||||||
|
currentRow := pos / width
|
||||||
|
if up := pos - width; up >= 0 {
|
||||||
|
result = append(result, up)
|
||||||
|
}
|
||||||
|
if down := pos + width; down < size {
|
||||||
|
result = append(result, down)
|
||||||
|
}
|
||||||
|
if left := pos - 1; left >= 0 && currentRow == (left/width) {
|
||||||
|
result = append(result, left)
|
||||||
|
}
|
||||||
|
if right := pos + 1; right < size && currentRow == (right/width) {
|
||||||
|
result = append(result, right)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdjacentTranslateCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
|
||||||
|
func GetAdjacentTranslateCoordinateXY[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) {
|
||||||
|
width := P(len(matrix))
|
||||||
|
height := P(len(matrix[0]))
|
||||||
|
if up := y - 1; up >= 0 {
|
||||||
|
result = append(result, NewPoint(x, up))
|
||||||
|
}
|
||||||
|
if down := y + 1; down < height {
|
||||||
|
result = append(result, NewPoint(x, down))
|
||||||
|
}
|
||||||
|
if left := x - 1; left >= 0 {
|
||||||
|
result = append(result, NewPoint(left, y))
|
||||||
|
}
|
||||||
|
if right := x + 1; right < width {
|
||||||
|
result = append(result, NewPoint(right, y))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdjacentTranslateCoordinateYX 获取一个基于 y、x 的二维矩阵中,特定位置相邻的最多四个平移方向(上下左右)的位置
|
||||||
|
func GetAdjacentTranslateCoordinateYX[T any, P generic.Number](matrix [][]T, x, y P) (result []Point[P]) {
|
||||||
|
width := P(len(matrix[0]))
|
||||||
|
height := P(len(matrix))
|
||||||
|
if up := y - 1; up >= 0 {
|
||||||
|
result = append(result, NewPoint(x, up))
|
||||||
|
}
|
||||||
|
if down := y + 1; down < height {
|
||||||
|
result = append(result, NewPoint(x, down))
|
||||||
|
}
|
||||||
|
if left := x - 1; left >= 0 {
|
||||||
|
result = append(result, NewPoint(left, y))
|
||||||
|
}
|
||||||
|
if right := x + 1; right < width {
|
||||||
|
result = append(result, NewPoint(right, y))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdjacentDiagonalsPos 获取一个连续位置的矩阵中,特定位置相邻的对角线最多四个方向的位置
|
||||||
|
func GetAdjacentDiagonalsPos[T any, P generic.Number](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) {
|
||||||
|
result = append(result, topLeft)
|
||||||
|
}
|
||||||
|
if topRight := pos - width + 1; topRight >= 0 && currentRow-1 == (topRight/width) {
|
||||||
|
result = append(result, topRight)
|
||||||
|
}
|
||||||
|
if bottomLeft := pos + width - 1; bottomLeft < size && currentRow+1 == (bottomLeft/width) {
|
||||||
|
result = append(result, bottomLeft)
|
||||||
|
}
|
||||||
|
if bottomRight := pos + width + 1; bottomRight < size && currentRow+1 == (bottomRight/width) {
|
||||||
|
result = append(result, bottomRight)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdjacentDiagonalsCoordinateXY 获取一个基于 x、y 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置
|
||||||
|
func GetAdjacentDiagonalsCoordinateXY[T any, P generic.Number](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 {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
if nx, ny := x+1, y-1; nx < width && ny >= 0 {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
if nx, ny := x-1, y+1; nx >= 0 && ny < height {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
if nx, ny := x+1, y+1; nx < width && ny < height {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdjacentDiagonalsCoordinateYX 获取一个基于 tx 的二维矩阵中,特定位置相邻的对角线最多四个方向的位置
|
||||||
|
func GetAdjacentDiagonalsCoordinateYX[T any, P generic.Number](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 {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
if nx, ny := x+1, y-1; nx < width && ny >= 0 {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
if nx, ny := x-1, y+1; nx >= 0 && ny < height {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
if nx, ny := x+1, y+1; nx < width && ny < height {
|
||||||
|
result = append(result, NewPoint(nx, ny))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdjacentPos 获取一个连续位置的矩阵中,特定位置相邻的最多八个方向的位置
|
||||||
|
func GetAdjacentPos[T any, P generic.Number](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]) {
|
||||||
|
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]) {
|
||||||
|
return append(GetAdjacentTranslateCoordinateYX(matrix, x, y), GetAdjacentDiagonalsCoordinateYX(matrix, x, y)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoordinateMatrixToPosMatrix 将二维矩阵转换为顺序的二维矩阵
|
||||||
|
func CoordinateMatrixToPosMatrix[V any](matrix [][]V) (width int, posMatrix []V) {
|
||||||
|
width = len(matrix)
|
||||||
|
height := len(matrix[0])
|
||||||
|
posMatrix = make([]V, width*height)
|
||||||
|
for x := 0; x < width; x++ {
|
||||||
|
for y := 0; y < height; y++ {
|
||||||
|
posMatrix[CoordinateToPos(width, x, y)] = matrix[x][y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue