网格寻路建立连接

This commit is contained in:
kercylan98 2023-06-19 14:15:21 +08:00
parent caa1512e1c
commit 62b6f209a3
2 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,71 @@
package navmesh
import (
"github.com/kercylan98/minotaur/utils/generic"
"github.com/kercylan98/minotaur/utils/geometry"
"github.com/kercylan98/minotaur/utils/maths"
)
type Navmesh[V generic.SignedNumber] struct {
meshShapes []*shape[V]
}
func (slf *Navmesh[V]) generateLink() {
refer := len(slf.meshShapes)
for i := 0; i < refer; i++ {
shapePkg := slf.meshShapes[i]
shape := shapePkg.Shape
shapeCentroid := geometry.CalcRectangleCentroid(shape)
shapeBoundingRadius := geometry.CalcBoundingRadiusWithCentroid(shape, shapeCentroid)
shapeEdges := shape.Edges()
for t := i + 1; t < len(slf.meshShapes); t++ {
targetShapePkg := slf.meshShapes[t]
targetShape := targetShapePkg.Shape
targetShapeCentroid := geometry.CalcRectangleCentroid(targetShape)
targetShapeBoundingRadius := geometry.CalcBoundingRadiusWithCentroid(shape, targetShapeCentroid)
centroidDistance := geometry.CalcDistance(geometry.DoublePointToCoordinate(shapeCentroid, targetShapeCentroid))
if centroidDistance > shapeBoundingRadius+targetShapeBoundingRadius {
continue
}
for _, shapeEdge := range shapeEdges {
for _, targetEdge := range targetShape.Edges() {
if !geometry.CalcLineIsCollinear(shapeEdge, targetEdge, V(maths.GetDefaultTolerance())) {
continue
}
var overlapLine, overlap = geometry.CalcLineIsOverlap(shapeEdge, targetEdge)
if !overlap {
continue
}
shapePkg.links = append(shapePkg.links, targetShapePkg)
targetShapePkg.links = append(targetShapePkg.links, shapePkg)
edgeAngle := geometry.CalcAngle(geometry.DoublePointToCoordinate(shapeCentroid, shapeEdge.GetStart()))
a1 := geometry.CalcAngle(geometry.DoublePointToCoordinate(shapeCentroid, overlapLine.GetStart()))
a2 := geometry.CalcAngle(geometry.DoublePointToCoordinate(shapeCentroid, overlapLine.GetEnd()))
a3 := geometry.CalcAngleDifference(edgeAngle, a1)
a4 := geometry.CalcAngleDifference(edgeAngle, a2)
if a3 < a4 {
shapePkg.portals = append(shapePkg.portals, geometry.NewLine(overlapLine.GetStart(), overlapLine.GetEnd()))
} else {
shapePkg.portals = append(shapePkg.portals, geometry.NewLine(overlapLine.GetEnd(), overlapLine.GetStart()))
}
edgeAngle = geometry.CalcAngle(geometry.DoublePointToCoordinate(targetShapeCentroid, targetEdge.GetStart()))
a1 = geometry.CalcAngle(geometry.DoublePointToCoordinate(targetShapeCentroid, overlapLine.GetStart()))
a2 = geometry.CalcAngle(geometry.DoublePointToCoordinate(targetShapeCentroid, overlapLine.GetEnd()))
a3 = geometry.CalcAngleDifference(edgeAngle, a1)
a4 = geometry.CalcAngleDifference(edgeAngle, a2)
if a3 < a4 {
targetShapePkg.portals = append(targetShapePkg.portals, geometry.NewLine(overlapLine.GetStart(), overlapLine.GetEnd()))
} else {
targetShapePkg.portals = append(targetShapePkg.portals, geometry.NewLine(overlapLine.GetEnd(), overlapLine.GetStart()))
}
}
}
}
}
}

View File

@ -0,0 +1,18 @@
package navmesh
import (
"github.com/kercylan98/minotaur/utils/generic"
"github.com/kercylan98/minotaur/utils/geometry"
)
func newShape[V generic.SignedNumber](s geometry.Shape[V]) *shape[V] {
return &shape[V]{
Shape: s,
}
}
type shape[V generic.SignedNumber] struct {
geometry.Shape[V]
links []*shape[V]
portals []geometry.Line[V]
}