Skip to content

Commit b4016e9

Browse files
reachtarunherenorvig
authored andcommitted
Implementation of Continuous World
* Model for ContinuousWorld * Added PolygonObstacle Class * Added HTML for Continuos World * Added JS for Continuous World * Implemented ContinuousWorldView Class
1 parent 65a00f5 commit b4016e9

3 files changed

Lines changed: 155 additions & 0 deletions

File tree

agents.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,28 @@ class Obstacle(Thing):
516516
class Wall(Obstacle):
517517
pass
518518

519+
520+
521+
# ______________________________________________________________________________
522+
# Continuous environment
523+
524+
class ContinuousWorld(Environment):
525+
""" Model for Continuous World. """
526+
def __init__(self, width=10, height=10):
527+
super(ContinuousWorld, self).__init__()
528+
self.width = width
529+
self.height = height
530+
531+
def add_obstacle(self, coordinates):
532+
self.things.append(PolygonObstacle(coordinates))
533+
534+
535+
class PolygonObstacle(Obstacle):
536+
def __init__(self, coordinates):
537+
""" Coordinates is a list of tuples. """
538+
super(PolygonObstacle, self).__init__()
539+
self.coordinates = coordinates
540+
519541
# ______________________________________________________________________________
520542
# Vacuum environment
521543

ipyviews.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from IPython.display import HTML, display, clear_output
2+
from agents import PolygonObstacle
3+
import time
4+
import __main__
5+
6+
7+
# ______________________________________________________________________________
8+
# Continuous environment
9+
10+
11+
_CONTINUOUS_WORLD_HTML = '''
12+
<div>
13+
<canvas class="main-robo-world" width="{0}" height="{1}" style="background:rgba(158, 167, 184, 0.2);" data-world_name="{2}" onclick="getPosition(this,event)"/>
14+
</div>
15+
16+
<script type="text/javascript">
17+
var all_polygons = {3};
18+
{4}
19+
</script>
20+
'''
21+
22+
with open('js/continuousworld.js', 'r') as js_file:
23+
_JS_CONTINUOUS_WORLD = js_file.read()
24+
25+
26+
class ContinuousWorldView:
27+
''' View for continuousworld Implementation in agents.py '''
28+
29+
def __init__(self, world, fill="#AAA"):
30+
self.time = time.time()
31+
self.world = world
32+
self.width = world.width
33+
self.height = world.height
34+
35+
def object_name(self):
36+
globals_in_main = {x: getattr(__main__, x) for x in dir(__main__)}
37+
for x in globals_in_main:
38+
if isinstance(globals_in_main[x], type(self)):
39+
if globals_in_main[x].time == self.time:
40+
return x
41+
42+
def handle_add_obstacle(self, vertices):
43+
""" Vertices must be a nestedtuple. This method
44+
is called from kernel.execute on completion of
45+
a polygon. """
46+
self.world.add_obstacle(vertices)
47+
self.show()
48+
49+
def handle_remove_obstacle(self):
50+
return NotImplementedError
51+
52+
def get_polygon_obstacles_coordinates(self):
53+
obstacle_coordiantes = []
54+
for thing in self.world.things:
55+
if isinstance(thing, PolygonObstacle):
56+
obstacle_coordiantes.append(thing.coordinates)
57+
return obstacle_coordiantes
58+
59+
def show(self):
60+
clear_output()
61+
total_html = _CONTINUOUS_WORLD_HTML.format(self.width, self.height, self.object_name(), str(self.get_polygon_obstacles_coordinates()), _JS_CONTINUOUS_WORLD)
62+
display(HTML(total_html))

js/continuousworld.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
var latest_output_area ="NONE"; // Jquery object for the DOM element of output area which was used most recently
2+
function handle_output(out, block){
3+
var output = out.content.data["text/html"];
4+
latest_output_area.html(output);
5+
}
6+
function polygon_complete(canvas, vertices){
7+
latest_output_area = $(canvas).parents('.output_subarea');
8+
var world_object_name = canvas.dataset.world_name;
9+
var command = world_object_name + ".handle_add_obstacle(" + JSON.stringify(vertices) + ")";
10+
console.log("Executing Command: " + command);
11+
var kernel = IPython.notebook.kernel;
12+
var callbacks = { 'iopub' : {'output' : handle_output}};
13+
kernel.execute(command,callbacks);
14+
}
15+
var canvas , ctx;
16+
function drawPolygon(array) {
17+
ctx.fillStyle = '#f00';
18+
ctx.beginPath();
19+
ctx.moveTo(array[0][0],array[0][1]);
20+
for(var i = 1;i<array.length;++i)
21+
{
22+
ctx.lineTo(array[i][0], array[i][1]);
23+
}
24+
ctx.closePath();
25+
ctx.fill();
26+
}
27+
var pArray = new Array();
28+
function getPosition(obj,event) {
29+
canvas = obj;
30+
ctx = canvas.getContext('2d');
31+
var x = new Number();
32+
var y = new Number();
33+
x = event.pageX;
34+
y = event.pageY;
35+
x -= $(canvas).offset().left;
36+
y -= $(canvas).offset().top;
37+
drawPoint(x,y);
38+
//draw dot
39+
if(pArray.length>1)
40+
{
41+
drawPoint(pArray[0][0],pArray[0][1]);
42+
}
43+
//check overlap
44+
if(ctx.isPointInPath(x, y) && (pArray.length>1)) {
45+
//Do something
46+
drawPolygon(pArray);
47+
polygon_complete(canvas,pArray);
48+
}
49+
else {
50+
var point = new Array();
51+
point.push(x,y);
52+
pArray.push(point);
53+
}
54+
}
55+
function drawPoint(x, y) {
56+
ctx.beginPath();
57+
ctx.arc(x, y, 5, 0, Math.PI*2);
58+
ctx.fillStyle = '#00f';
59+
ctx.fill();
60+
ctx.closePath();
61+
}
62+
function initalizeObstacles(objects) {
63+
canvas = $('canvas.main-robo-world').get(0);
64+
ctx = canvas.getContext('2d');
65+
$('canvas.main-robo-world').removeClass('main-robo-world');
66+
for(var i=0;i<objects.length;++i) {
67+
drawPolygon(objects[i]);
68+
}
69+
pArray.length = 0;
70+
}
71+
initalizeObstacles(all_polygons);

0 commit comments

Comments
 (0)