✨ 增加圆形相关处理函数
This commit is contained in:
parent
d10c05dfe1
commit
c0570392bf
|
@ -123,7 +123,7 @@ func (slf *Moving2D) handle() {
|
|||
if interval == 0 {
|
||||
continue
|
||||
}
|
||||
distance := geometry.CalcDistance(x, y, entity.x, entity.y)
|
||||
distance := geometry.CalcDistanceWithCoordinate(x, y, entity.x, entity.y)
|
||||
moveDistance := interval * (entity.GetSpeed() / (slf.timeUnit / 1000 / 1000))
|
||||
if moveDistance >= distance || (x == entity.x && y == entity.y) {
|
||||
entity.SetPosition(entity.x, entity.y)
|
||||
|
|
|
@ -177,7 +177,7 @@ func (slf *AOI2D) refresh(entity game.AOIEntity2D) {
|
|||
focus := slf.focus[guid]
|
||||
for eg, e := range focus {
|
||||
ex, ey := e.GetPosition()
|
||||
if geometry.CalcDistance(x, y, ex, ey) > vision {
|
||||
if geometry.CalcDistanceWithCoordinate(x, y, ex, ey) > vision {
|
||||
delete(focus, eg)
|
||||
delete(slf.focus[eg], guid)
|
||||
}
|
||||
|
@ -243,13 +243,13 @@ func (slf *AOI2D) rangeVisionAreaEntities(entity game.AOIEntity2D, handle func(g
|
|||
} else {
|
||||
areaY = y
|
||||
}
|
||||
areaDistance := geometry.CalcDistance(x, y, areaX, areaY)
|
||||
areaDistance := geometry.CalcDistanceWithCoordinate(x, y, areaX, areaY)
|
||||
if areaDistance <= vision {
|
||||
for eg, e := range slf.areas[w][h] {
|
||||
if eg == guid {
|
||||
continue
|
||||
}
|
||||
if ex, ey := e.GetPosition(); geometry.CalcDistance(x, y, ex, ey) > vision {
|
||||
if ex, ey := e.GetPosition(); geometry.CalcDistanceWithCoordinate(x, y, ex, ey) > vision {
|
||||
continue
|
||||
}
|
||||
handle(eg, e)
|
||||
|
|
|
@ -37,9 +37,9 @@ func ExampleFind() {
|
|||
}
|
||||
|
||||
paths := astar.Find[geometry.Point[int], int](graph, geometry.NewPoint(1, 1), geometry.NewPoint(8, 6), func(a, b geometry.Point[int]) int {
|
||||
return geometry.CalcDistance(geometry.DoublePointToCoordinate(a, b))
|
||||
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(a, b))
|
||||
}, func(a, b geometry.Point[int]) int {
|
||||
return geometry.CalcDistance(geometry.DoublePointToCoordinate(a, b))
|
||||
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(a, b))
|
||||
})
|
||||
|
||||
for _, path := range paths {
|
||||
|
|
|
@ -5,8 +5,53 @@ import (
|
|||
"math"
|
||||
)
|
||||
|
||||
// Circle 圆形
|
||||
type Circle[V generic.SignedNumber] struct {
|
||||
Shape[V]
|
||||
radius V
|
||||
centroid Point[V]
|
||||
initCentroid bool
|
||||
}
|
||||
|
||||
// Radius 获取圆形半径
|
||||
func (slf Circle[V]) Radius() V {
|
||||
if slf.radius > V(-0) {
|
||||
return slf.radius
|
||||
}
|
||||
for _, point := range slf.Points() {
|
||||
slf.radius = CalcDistanceWithPoint(slf.Centroid(), point)
|
||||
return slf.radius
|
||||
}
|
||||
panic("circle without any points")
|
||||
}
|
||||
|
||||
// Centroid 获取圆形质心位置
|
||||
func (slf Circle[V]) Centroid() Point[V] {
|
||||
if slf.initCentroid {
|
||||
return slf.centroid
|
||||
}
|
||||
slf.centroid = CalcRectangleCentroid(slf.Shape)
|
||||
slf.initCentroid = true
|
||||
return slf.centroid
|
||||
}
|
||||
|
||||
// Overlap 与另一个圆是否发生重叠
|
||||
func (slf Circle[V]) Overlap(circle Circle[V]) bool {
|
||||
return CalcDistanceWithPoint(slf.Centroid(), circle.Centroid())/2 > slf.radius
|
||||
}
|
||||
|
||||
// Area 获取圆形面积
|
||||
func (slf Circle[V]) Area() V {
|
||||
return V(math.Pi * math.Pow(float64(slf.Radius()), 2))
|
||||
}
|
||||
|
||||
// Length 获取圆的周长
|
||||
func (slf Circle[V]) Length() V {
|
||||
return V(2 * math.Pi * float64(slf.Radius()))
|
||||
}
|
||||
|
||||
// GenerateCircle 通过传入圆的半径和需要的点数量,生成一个圆
|
||||
func GenerateCircle[V generic.SignedNumber](radius V, points int) Shape[V] {
|
||||
func GenerateCircle[V generic.SignedNumber](radius V, points int) Circle[V] {
|
||||
angle := 2.0 * math.Pi / float64(points)
|
||||
var shape = make(Shape[V], points)
|
||||
for i := 0; i < points; i++ {
|
||||
|
@ -15,5 +60,5 @@ func GenerateCircle[V generic.SignedNumber](radius V, points int) Shape[V] {
|
|||
y := radius * V(math.Sin(curAngle))
|
||||
shape = append(shape, NewPoint(x, y))
|
||||
}
|
||||
return shape
|
||||
return shape.ToCircle()
|
||||
}
|
||||
|
|
|
@ -109,11 +109,16 @@ func CalcDirection[V generic.SignedNumber](x1, y1, x2, y2 V) Direction {
|
|||
return DirectionUnknown
|
||||
}
|
||||
|
||||
// CalcDistance 计算两点之间的距离
|
||||
func CalcDistance[V generic.SignedNumber](x1, y1, x2, y2 V) V {
|
||||
// CalcDistanceWithCoordinate 计算两点之间的距离
|
||||
func CalcDistanceWithCoordinate[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)))
|
||||
}
|
||||
|
||||
// CalcDistanceWithPoint 计算两点之间的距离
|
||||
func CalcDistanceWithPoint[V generic.SignedNumber](point1, point2 Point[V]) V {
|
||||
return CalcDistanceWithCoordinate(DoublePointToCoordinate(point1, point2))
|
||||
}
|
||||
|
||||
// CalcDistanceSquared 计算两点之间的平方距离
|
||||
// - 这个函数的主要用途是在需要计算两点之间距离的情况下,但不需要得到实际的距离值,而只需要比较距离大小。因为平方根运算相对较为耗时,所以在只需要比较大小的情况下,通常会使用平方距离。
|
||||
func CalcDistanceSquared[V generic.SignedNumber](x1, y1, x2, y2 V) V {
|
||||
|
|
|
@ -54,7 +54,7 @@ func (slf LineSegment[V]) GetEnd() Point[V] {
|
|||
|
||||
// GetLength 获取该线段的长度
|
||||
func (slf LineSegment[V]) GetLength() V {
|
||||
return CalcDistance(DoublePointToCoordinate(slf.GetStart(), slf.GetEnd()))
|
||||
return CalcDistanceWithCoordinate(DoublePointToCoordinate(slf.GetStart(), slf.GetEnd()))
|
||||
}
|
||||
|
||||
// PointOnLineSegmentWithCoordinate 通过一个线段两个点的位置和一个点的坐标,判断这个点是否在一条线段上
|
||||
|
|
|
@ -74,7 +74,7 @@ func (slf *NavMesh[V]) Find(point geometry.Point[V], maxDistance V) (distance V,
|
|||
break
|
||||
}
|
||||
br := geometry.CalcBoundingRadius(meshShape.Shape)
|
||||
distance := geometry.CalcDistance(geometry.DoublePointToCoordinate(
|
||||
distance := geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(
|
||||
geometry.CalcRectangleCentroid(meshShape.Shape),
|
||||
point,
|
||||
))
|
||||
|
@ -111,13 +111,13 @@ func (slf *NavMesh[V]) FindPath(start, end geometry.Point[V]) (result []geometry
|
|||
for _, meshShape := range slf.meshShapes {
|
||||
br := meshShape.BoundingRadius()
|
||||
|
||||
distance := geometry.CalcDistance(geometry.DoublePointToCoordinate(meshShape.Centroid(), start))
|
||||
distance := geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(meshShape.Centroid(), start))
|
||||
if (distance <= startDistance || startDistance == V(-1)) && distance <= br && meshShape.Contains(start) {
|
||||
startShape = meshShape
|
||||
startDistance = distance
|
||||
}
|
||||
|
||||
distance = geometry.CalcDistance(geometry.DoublePointToCoordinate(meshShape.Centroid(), end))
|
||||
distance = geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(meshShape.Centroid(), end))
|
||||
if (distance <= endDistance || endDistance == V(-1)) && distance <= br && meshShape.Contains(end) {
|
||||
endShape = meshShape
|
||||
endDistance = distance
|
||||
|
@ -127,7 +127,7 @@ func (slf *NavMesh[V]) FindPath(start, end geometry.Point[V]) (result []geometry
|
|||
if endShape == nil && slf.meshShrinkAmount > V(0) {
|
||||
for _, meshShape := range slf.meshShapes {
|
||||
br := meshShape.BoundingRadius() + slf.meshShrinkAmount
|
||||
distance := geometry.CalcDistance(geometry.DoublePointToCoordinate(meshShape.Centroid(), end))
|
||||
distance := geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(meshShape.Centroid(), end))
|
||||
if distance <= br {
|
||||
_, projectionDistance := geometry.ProjectionPointToShape(end, meshShape.Shape)
|
||||
if projectionDistance <= slf.meshShrinkAmount && projectionDistance < endDistance {
|
||||
|
@ -145,7 +145,7 @@ func (slf *NavMesh[V]) FindPath(start, end geometry.Point[V]) (result []geometry
|
|||
if startShape == nil && slf.meshShrinkAmount > 0 {
|
||||
for _, meshShape := range slf.meshShapes {
|
||||
br := meshShape.BoundingRadius() + slf.meshShrinkAmount
|
||||
distance := geometry.CalcDistance(geometry.DoublePointToCoordinate(meshShape.Centroid(), start))
|
||||
distance := geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(meshShape.Centroid(), start))
|
||||
if distance <= br {
|
||||
_, projectionDistance := geometry.ProjectionPointToShape(start, meshShape.Shape)
|
||||
if projectionDistance <= slf.meshShrinkAmount && projectionDistance < startDistance {
|
||||
|
@ -165,9 +165,9 @@ func (slf *NavMesh[V]) FindPath(start, end geometry.Point[V]) (result []geometry
|
|||
}
|
||||
|
||||
path := astar.Find[*shape[V], V](slf, startShape, endShape, func(a, b *shape[V]) V {
|
||||
return geometry.CalcDistance(geometry.DoublePointToCoordinate(a.centroid, b.centroid))
|
||||
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(a.centroid, b.centroid))
|
||||
}, func(a, b *shape[V]) V {
|
||||
return geometry.CalcDistance(geometry.DoublePointToCoordinate(a.centroid, b.centroid))
|
||||
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(a.centroid, b.centroid))
|
||||
})
|
||||
|
||||
if len(path) == 0 {
|
||||
|
@ -223,7 +223,7 @@ func (slf *NavMesh[V]) generateLink() {
|
|||
targetShapePkg := slf.meshShapes[t]
|
||||
targetShapeCentroid := targetShapePkg.Centroid()
|
||||
targetShapeBoundingRadius := targetShapePkg.BoundingRadius()
|
||||
centroidDistance := geometry.CalcDistance(geometry.DoublePointToCoordinate(shapeCentroid, targetShapeCentroid))
|
||||
centroidDistance := geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(shapeCentroid, targetShapeCentroid))
|
||||
if centroidDistance > shapeBoundingRadius+targetShapeBoundingRadius {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -45,5 +45,5 @@ func (slf *shape[V]) IsWall() bool {
|
|||
}
|
||||
|
||||
func (slf *shape[V]) GetCost(point geometry.Point[V]) V {
|
||||
return geometry.CalcDistance(geometry.DoublePointToCoordinate(slf.Centroid(), point))
|
||||
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(slf.Centroid(), point))
|
||||
}
|
||||
|
|
|
@ -59,6 +59,26 @@ func (slf Point[V]) Copy() Point[V] {
|
|||
return PointCopy(slf)
|
||||
}
|
||||
|
||||
// Add 得到加上 point 后的点
|
||||
func (slf Point[V]) Add(point Point[V]) Point[V] {
|
||||
return slf.GetOffset(point.GetXY())
|
||||
}
|
||||
|
||||
// Sub 得到减去 point 后的点
|
||||
func (slf Point[V]) Sub(point Point[V]) Point[V] {
|
||||
return NewPoint(slf.GetX()-point.GetX(), slf.GetY()-point.GetY())
|
||||
}
|
||||
|
||||
// Mul 得到乘以 point 后的点
|
||||
func (slf Point[V]) Mul(point Point[V]) Point[V] {
|
||||
return NewPoint(slf.GetX()*point.GetX(), slf.GetY()*point.GetY())
|
||||
}
|
||||
|
||||
// Div 得到除以 point 后的点
|
||||
func (slf Point[V]) Div(point Point[V]) Point[V] {
|
||||
return NewPoint(slf.GetX()/point.GetX(), slf.GetY()/point.GetY())
|
||||
}
|
||||
|
||||
// NewPointCap 创建一个由 x、y 坐标组成的点,这个点具有一个数据容量
|
||||
func NewPointCap[V generic.SignedNumber, D any](x, y V) PointCap[V, D] {
|
||||
return PointCap[V, D]{
|
||||
|
|
|
@ -84,6 +84,12 @@ func (slf Shape[V]) Contains(point Point[V]) bool {
|
|||
return inside
|
||||
}
|
||||
|
||||
// ToCircle 将形状转换为圆形进行处理
|
||||
// - 当形状非圆形时将会产生意外情况
|
||||
func (slf Shape[V]) ToCircle() Circle[V] {
|
||||
return Circle[V]{slf}
|
||||
}
|
||||
|
||||
// String 将该形状转换为可视化的字符串进行返回
|
||||
func (slf Shape[V]) String() string {
|
||||
var result string
|
||||
|
@ -412,7 +418,7 @@ func CalcBoundingRadius[V generic.SignedNumber](shape Shape[V]) V {
|
|||
var boundingRadius V
|
||||
var centroid = CalcRectangleCentroid(shape)
|
||||
for _, point := range shape.Points() {
|
||||
distance := CalcDistance(DoublePointToCoordinate(centroid, point))
|
||||
distance := CalcDistanceWithCoordinate(DoublePointToCoordinate(centroid, point))
|
||||
if distance > boundingRadius {
|
||||
boundingRadius = distance
|
||||
}
|
||||
|
@ -424,7 +430,7 @@ func CalcBoundingRadius[V generic.SignedNumber](shape Shape[V]) V {
|
|||
func CalcBoundingRadiusWithCentroid[V generic.SignedNumber](shape Shape[V], centroid Point[V]) V {
|
||||
var boundingRadius V
|
||||
for _, point := range shape.Points() {
|
||||
distance := CalcDistance(DoublePointToCoordinate(centroid, point))
|
||||
distance := CalcDistanceWithCoordinate(DoublePointToCoordinate(centroid, point))
|
||||
if distance > boundingRadius {
|
||||
boundingRadius = distance
|
||||
}
|
||||
|
@ -459,7 +465,7 @@ func ProjectionPointToShape[V generic.SignedNumber](point Point[V], shape Shape[
|
|||
|
||||
for _, edge := range shape.Edges() {
|
||||
projectedPoint := CalcProjectionPoint(edge, point)
|
||||
distance := CalcDistance(DoublePointToCoordinate(point, projectedPoint))
|
||||
distance := CalcDistanceWithCoordinate(DoublePointToCoordinate(point, projectedPoint))
|
||||
if !hasClosestProjection || distance < closestDistance {
|
||||
closestDistance = distance
|
||||
closestProjection = projectedPoint
|
||||
|
|
Loading…
Reference in New Issue