From f7c37016cef946c9e8e3a4366139c43fee5f8eb8 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Mon, 4 Mar 2024 17:56:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20geometry=20?= =?UTF-8?q?=E5=8C=85=20SimpleCircle.Projection=20=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86=E6=B3=A8=E9=87=8A=E5=8F=8A?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E5=88=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/collection/listings/priority_slice.go | 4 ++-- utils/geometry/position.go | 13 +++++++++++ utils/geometry/simple_circle.go | 18 +++++++++++----- utils/random/number.go | 24 +++++++++++++++++++++ utils/times/format.go | 6 ++++++ 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/utils/collection/listings/priority_slice.go b/utils/collection/listings/priority_slice.go index eb770585..6877b488 100644 --- a/utils/collection/listings/priority_slice.go +++ b/utils/collection/listings/priority_slice.go @@ -5,7 +5,7 @@ import ( "sort" ) -// NewPrioritySlice 创建一个优先级切片 +// NewPrioritySlice 创建一个优先级切片,优先级越低越靠前 func NewPrioritySlice[V any](lengthAndCap ...int) *PrioritySlice[V] { p := &PrioritySlice[V]{} if len(lengthAndCap) > 0 { @@ -19,7 +19,7 @@ func NewPrioritySlice[V any](lengthAndCap ...int) *PrioritySlice[V] { return p } -// PrioritySlice 是一个优先级切片 +// PrioritySlice 是一个优先级切片,优先级越低越靠前 type PrioritySlice[V any] struct { items []*priorityItem[V] } diff --git a/utils/geometry/position.go b/utils/geometry/position.go index c50caca5..124fd939 100644 --- a/utils/geometry/position.go +++ b/utils/geometry/position.go @@ -109,6 +109,19 @@ func (slf Point[V]) Max(point Point[V]) Point[V] { return NewPoint(x, y) } +// Move 返回向特定角度移动特定距离后的新的位置,其中 angle 期待的角度范围是 -180~180 +func (slf Point[V]) Move(angle, direction V) Point[V] { + df := float64(direction) + // 将角度转换为弧度 + radian := float64(angle) * (math.Pi / 180.0) + + // 计算新的坐标 + newX := float64(slf.GetX()) + df*math.Cos(radian) + newY := float64(slf.GetY()) + df*math.Sin(radian) + + return NewPoint(V(newX), V(newY)) +} + // Min 返回两个位置中每个维度的最小值组成的新的位置 func (slf Point[V]) Min(point Point[V]) Point[V] { x, y := slf.GetXY() diff --git a/utils/geometry/simple_circle.go b/utils/geometry/simple_circle.go index 9cc93a73..e3fff18a 100644 --- a/utils/geometry/simple_circle.go +++ b/utils/geometry/simple_circle.go @@ -29,6 +29,11 @@ func (sc SimpleCircle[V]) String() string { return fmt.Sprintf("SimpleCircle{centroid: %v, %v, radius: %v}", sc.centroid.GetX(), sc.centroid.GetY(), sc.radius) } +// IsZero 反映该圆形是否为零值的无效圆形 +func (sc SimpleCircle[V]) IsZero() bool { + return sc.radius == V(0) +} + // Centroid 获取圆形质心位置 func (sc SimpleCircle[V]) Centroid() Point[V] { return sc.centroid @@ -74,15 +79,18 @@ func (sc SimpleCircle[V]) Area() V { return sc.radius * sc.radius } -// Projection 获取圆形投影到另一个圆形的特定比例下的位置和半径 +// Projection 获取圆形投影到另一个圆形的特定比例下的位置和半径(同心合并) func (sc SimpleCircle[V]) Projection(circle SimpleCircle[V], ratio float64) SimpleCircle[V] { // 计算圆心朝目标按比例移动后的位置 - distance := float64(sc.Centroid().Distance(circle.centroid)) + distance := sc.Centroid().Distance(circle.Centroid()) moveDistance := distance * ratio - newX := float64(sc.CentroidX()) + moveDistance*(float64(circle.CentroidX())-float64(sc.CentroidX()))/distance - newY := float64(sc.CentroidY()) + moveDistance*(float64(circle.CentroidY())-float64(sc.CentroidY()))/distance + newX := float64(circle.CentroidX()) + moveDistance*(float64(sc.CentroidX())-float64(circle.CentroidX()))/distance + newY := float64(circle.CentroidY()) + moveDistance*(float64(sc.CentroidY())-float64(circle.CentroidY()))/distance + + // 计算新的半径 + newRadius := float64(sc.radius) + (float64(circle.radius)-float64(sc.radius))*(1-ratio) - return NewSimpleCircle(V(float64(sc.radius)*ratio), NewPoint(V(newX), V(newY))) + return NewSimpleCircle(V(newRadius), NewPoint(V(newX), V(newY))) } // Length 获取圆的周长 diff --git a/utils/random/number.go b/utils/random/number.go index 2a42e4a2..8ad0c13f 100644 --- a/utils/random/number.go +++ b/utils/random/number.go @@ -13,6 +13,30 @@ func Int64(min int64, max int64) int64 { return min + rand.Int63n(max+1-min) } +// Int32 返回一个介于min和max之间的的int32类型的随机数。 +func Int32(min int32, max int32) int32 { + if min == max { + return min + } + return int32(Int64(int64(min), int64(max))) +} + +// Float32Range 返回一个介于min和max之间的的float32类型的随机数。 +func Float32Range(min float32, max float32) float32 { + if min == max { + return min + } + return min + rand.Float32()*(max-min) +} + +// Float64Range 返回一个介于min和max之间的的float64类型的随机数。 +func Float64Range(min float64, max float64) float64 { + if min == max { + return min + } + return min + rand.Float64()*(max-min) +} + // Int 返回一个介于min和max之间的的int类型的随机数。 func Int(min int, max int) int { if min == max { diff --git a/utils/times/format.go b/utils/times/format.go index 7f549c7b..8b1a4741 100644 --- a/utils/times/format.go +++ b/utils/times/format.go @@ -2,6 +2,7 @@ package times import ( "fmt" + "github.com/kercylan98/minotaur/utils/generic" "math" "strconv" "time" @@ -60,3 +61,8 @@ func IntervalFormat(time1, time2 time.Time) string { } return res } + +// ToSecDuration 转换为秒级 time.Duration +func ToSecDuration[V generic.Number](v V) time.Duration { + return Second * time.Duration(int64(v)) +}