Skip to content

Commit 40e4c1f

Browse files
committed
fix: search ouf of area
1 parent 72f927a commit 40e4c1f

File tree

2 files changed

+62
-27
lines changed

2 files changed

+62
-27
lines changed

demo/recast/main.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,15 @@ func main() {
156156
}
157157
}
158158

159-
drawTriangles(triangles, rl.LightGray, true)
159+
drawTriangles(triangles, rl.LightGray)
160160

161161
for _, extraObstacle := range extraObstacles {
162162
drawArea(extraObstacle.Points(), rl.Gray)
163163
}
164164

165-
//if isDrawGraph {
166-
// drawGraph(pathfinder.GraphWithSearchPath(graphId, start, dest))
167-
//}
165+
if isDrawGraph {
166+
drawGraph(pathfinder.Graph(graphId))
167+
}
168168
drawPath(start, dest, path, camera.Zoom, true)
169169

170170
rl.EndMode2D()
@@ -226,19 +226,13 @@ func drawPath(start, dest geom.Vector2, path []geom.Vector2, zoom float32, skipN
226226
}
227227
}
228228

229-
func drawTriangles(triangles []recast.Triangle, color rl.Color, drawEdges ...bool) {
229+
func drawTriangles(triangles []recast.Triangle, color rl.Color) {
230230
for _, pp := range triangles {
231231
rl.DrawTriangleFan([]rl.Vector2{
232232
rl.NewVector2(pp[0].X, -pp[0].Y),
233233
rl.NewVector2(pp[1].X, -pp[1].Y),
234234
rl.NewVector2(pp[2].X, -pp[2].Y),
235235
}, color)
236-
237-
if len(drawEdges) > 0 {
238-
rl.DrawLineV(rl.NewVector2(pp[0].X, -pp[0].Y), rl.NewVector2(pp[1].X, -pp[1].Y), rl.Gray)
239-
rl.DrawLineV(rl.NewVector2(pp[1].X, -pp[1].Y), rl.NewVector2(pp[2].X, -pp[2].Y), rl.Gray)
240-
rl.DrawLineV(rl.NewVector2(pp[0].X, -pp[0].Y), rl.NewVector2(pp[2].X, -pp[2].Y), rl.Gray)
241-
}
242236
}
243237
}
244238

@@ -273,7 +267,7 @@ func drawArea(polygon []geom.Vector2, color rl.Color) {
273267
func drawGraph(graph map[geom.Vector2][]geom.Vector2) {
274268
for p, elems := range graph {
275269
for _, elem := range elems {
276-
rl.DrawLine(int32(p.X), int32(p.Y), int32(elem.X), int32(elem.Y), rl.NewColor(230, 41, 55, 30))
270+
rl.DrawLineV(rl.NewVector2(p.X, -p.Y), rl.NewVector2(elem.X, -elem.Y), rl.DarkGray)
277271
}
278272
}
279273
}

graphs/recast/recast.go

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type Recast struct {
3232
// extra obstacles
3333
obstaclePool *obstaclePool
3434
extraClippedPolygons []*mesh.Polygon
35+
extraEdges []*edge
3536
extraObstacleId2ClippedPoly map[obstaclePolyPair]goclipper2.PathsD
3637
}
3738

@@ -443,12 +444,25 @@ func (r *Recast) generateGraph() graphs.Graph[geom.Vector2] {
443444

444445
func (r *Recast) prepareEdges(edgeLen int) {
445446
r.edges = make([]*edge, 0, edgeLen)
446-
for _, polygon := range r.extraClippedPolygons {
447+
for _, polygon := range r.polygons {
447448
r.edges = append(r.edges, polyToEdges(polygon.Points())...)
448449
for _, hole := range polygon.Holes() {
449450
r.edges = append(r.edges, polyToEdges(hole.Points())...)
450451
}
451452
}
453+
454+
extraObstacles := r.obstaclePool.GetList()
455+
for _, extraObstacle := range extraObstacles {
456+
r.edges = append(r.edges, polyToEdges(extraObstacle.Points())...)
457+
}
458+
459+
r.extraEdges = make([]*edge, 0, edgeLen)
460+
for _, polygon := range r.extraClippedPolygons {
461+
r.extraEdges = append(r.extraEdges, polyToEdges(polygon.Points())...)
462+
for _, hole := range polygon.Holes() {
463+
r.extraEdges = append(r.extraEdges, polyToEdges(hole.Points())...)
464+
}
465+
}
452466
}
453467

454468
func polyToEdges(points []geom.Vector2) []*edge {
@@ -588,26 +602,53 @@ func onSegment(p, q, r geom.Vector2) bool {
588602
return qX <= math.Max(pX, rX) && qX >= math.Min(pX, rX) && qY <= math.Max(pY, rY) && qY >= math.Min(pY, rY)
589603
}
590604

605+
// pointOnSegment helper function for check point on segment with epsilon
606+
func pointOnSegment(p, a, b geom.Vector2, eps float64) bool {
607+
var (
608+
pX, pY = float64(p.X), float64(p.Y)
609+
aX, aY = float64(a.X), float64(a.Y)
610+
bX, bY = float64(b.X), float64(b.Y)
611+
)
612+
613+
if pX < math.Min(aX, bX)-eps || pX > math.Max(aX, bX)+eps ||
614+
pY < math.Min(aY, bY)-eps || pY > math.Max(aY, bY)+eps {
615+
return false
616+
}
617+
618+
cross := (b.X-a.X)*(p.Y-a.Y) - (b.Y-a.Y)*(p.X-a.X)
619+
return math.Abs(float64(cross)) <= eps
620+
}
621+
591622
func (r *Recast) getVisiblePoints(point geom.Vector2) []geom.Vector2 {
592-
visiblePoints := make([]geom.Vector2, len(r.vertices))
623+
visiblePoints := make([]geom.Vector2, len(r.extraEdges))
593624
count := 0
594625

595-
// TODO better but not so accurate :( ~99853ns
596-
for _, v := range r.vertices {
597-
hasIntersection := false
598-
for _, edge := range r.edges {
599-
if lineSegmentIntersection(edge.a, edge.b, v, point) {
600-
hasIntersection = true
601-
break
602-
}
603-
}
604-
605-
if !hasIntersection {
606-
visiblePoints[count] = v
626+
// TODO very fast check ~11146ns
627+
for _, edge := range r.extraEdges {
628+
if pointOnSegment(point, edge.a, edge.b, 1e-1) {
629+
visiblePoints[count] = edge.a
630+
count++
631+
visiblePoints[count] = edge.b
607632
count++
608633
}
609634
}
610635

636+
// TODO better but not so accurate :( ~99853ns
637+
//for _, v := range r.vertices {
638+
// hasIntersection := false
639+
// for _, edge := range r.edges {
640+
// if lineSegmentIntersection(edge.a, edge.b, v, point) {
641+
// hasIntersection = true
642+
// break
643+
// }
644+
// }
645+
//
646+
// if !hasIntersection {
647+
// visiblePoints[count] = v
648+
// count++
649+
// }
650+
//}
651+
611652
// TODO more accurate but expensive :( ~190585ns
612653
//for _, polygon := range r.polygons {
613654
// points := polygon.Points()
@@ -634,7 +675,7 @@ func (r *Recast) closestPointOnPolygon(startPoint geom.Vector2) (geom.Vector2, b
634675
exist := false
635676

636677
// Check exterior ring
637-
for _, polygon := range r.clippedPolygons {
678+
for _, polygon := range r.extraClippedPolygons {
638679
clippedPolygon := polygon.Points()
639680
for i := 0; i < len(clippedPolygon); i++ {
640681
p1 := clippedPolygon[i]

0 commit comments

Comments
 (0)