-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpath.py
123 lines (99 loc) · 4.22 KB
/
path.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
'''Path container to support easy path following by Agents
Created for HIT3046 AI for Games by Clinton Woodward cwoodward@swin.edu.au
'''
from random import random, uniform
from matrix33 import Matrix33
from vector2d import Vector2D
from graphics import egi
from math import pi
TWO_PI = pi * 2.0
def Vec2DRotateAroundOrigin(vec, rads):
''' Rotates a vector a given angle (in radians) around the origin.
Note: the vec parameter is altered (does not return a new vector. '''
mat = Matrix33()
mat.rotate_update(rads)
mat.transform_vector2d(vec)
class Path(object):
''' Container to hold a number of way points and a cursor to the
current way point. The cursor can be moved to the next way point by
calling set_next_way_pt(). Paths can be open or looped. '''
def __init__(self, num_pts=0, minx=0, miny=0, maxx=0, maxy=0, looped=False):
''' If number of points (num_pts) is provided, a path of random
non-overlapping waypoints will be created in the region specified
by the min/max x/y values provided. If the path is looped, the last
way point is connected to the first. '''
self.looped = looped
self._num_pts = num_pts
self._cur_pt_idx = -1
if num_pts > 0:
self.create_random_path(num_pts, minx, miny, maxx, maxy)
def current_way_pt(self):
''' Return the way point of the path indicated by the current point
index. '''
return self._way_pts[self._cur_pt_idx]
def is_finished(self):
''' Return True if at the end of the path. '''
return self._cur_pt_idx >= self._num_pts - 1
def create_random_path(self, num_pts, minx, miny, maxx, maxy):
''' Creates random path within the rectangle described by the
min/max values. Stores and returns path. '''
self.clear()
midX = (maxx + minx) / 2.0;
midY = (maxy + miny) / 2.0;
smaller = min(midX, midY);
spacing = TWO_PI / num_pts;
for i in range(num_pts):
radial_dist = uniform(smaller*0.2, smaller)
temp = Vector2D(radial_dist, 0.0)
Vec2DRotateAroundOrigin(temp, i*spacing)
temp.x += midX
temp.y += midY
self._way_pts.append(temp)
self._reset() # reset num_pts and cur_pt_idx
return self._way_pts;
def add_way_point(self, new_pt):
''' Add the waypoint to the end of the path.'''
self._way_pts.append(new_pt)
self._num_pts += 1
def set_pts(self, path_pts):
''' Replace our internal set of points with the container of points
provided. '''
self._way_pts = path_pts
self._reset()
def _reset(self):
''' Point to the first waypoint and set the limit count based on the
number of points we've been given. '''
self._cur_pt_idx = 0
self._num_pts = len(self._way_pts)
def clear(self):
''' Remove all way points and reset internal counters. '''
self._way_pts = []
self._cur_pt_idx = 0
self._num_pts = 0
def get_pts(self):
''' Simple wrapper to return a reference to the internal list of
points.'''
return self._way_pts
def render(self):
''' Draw the path, open or closed, using the current pen colour. '''
for index, wp in enumerate(self._way_pts):
egi.blue_pen()
filled = False
if(index < self._cur_pt_idx):
egi.green_pen()
if(index == self._cur_pt_idx):
egi.orange_pen()
filled = True
egi.circle(pos=wp, radius=5, filled=filled, slices=32)
egi.blue_pen()
if self.looped:
egi.closed_shape(self._way_pts)
else:
egi.polyline(self._way_pts)
def set_next_way_pt(self):
''' Update the current point to the next in the path list.
Resets to the first point if looped is True. '''
assert self._num_pts > 0
self._cur_pt_idx += 1
if self.is_finished() and self.looped:
self._cur_pt_idx = 0