vRp.CD2g_test/utils/geometry/position.go

135 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
// NewPointCap 创建一个由 x、y 坐标组成的点,这个点具有一个数据容量
func NewPointCap[V generic.Number, 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] {
return PointCap[V, D]{
Point: NewPoint(x, y),
Data: data,
}
}
// PointCap 表示了一个由 x、y 坐标组成的点,这个点具有一个数据容量
type PointCap[V generic.Number, D any] struct {
Point[V]
Data D
}
// GetData 获取数据
func (slf PointCap[V, D]) GetData() D {
return slf.Data
}
// 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
}