From fce4a85d80be5a0add62869a08a283c3741c456f Mon Sep 17 00:00:00 2001 From: Matthew Saponaro Date: Tue, 5 Apr 2022 15:29:06 -0400 Subject: [PATCH 1/9] adding heading information and created setxy function which sets the agents position to the specified parameters --- mesa/agent.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mesa/agent.py b/mesa/agent.py index 6d3d67919c6..2a5bde38616 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -28,6 +28,7 @@ def __init__(self, unique_id: int, model: "Model") -> None: self.unique_id = unique_id self.model = model self.pos: Optional[Position] = None + self.heading = 90 def step(self) -> None: """A single step of the agent.""" @@ -36,6 +37,10 @@ def step(self) -> None: def advance(self) -> None: pass + def setxy(self, x,y): + """Sets the current position to the specified x,y parameters""" + self.pos = (x,y) + @property def random(self) -> Random: return self.model.random From 1e4e46feb168ecaaf1d05b89d7f46920f5fbf3f6 Mon Sep 17 00:00:00 2001 From: GaelLucero Date: Fri, 8 Apr 2022 15:20:33 -0400 Subject: [PATCH 2/9] created distancexy function, which gives you the distance of the agent and the given coordinate and distance function, which gives you the distance between the agent and another agent --- mesa/agent.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index 2a5bde38616..0f19278efbc 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -37,9 +37,17 @@ def step(self) -> None: def advance(self) -> None: pass - def setxy(self, x,y): + def setxy(self, x, y): """Sets the current position to the specified x,y parameters""" - self.pos = (x,y) + self.pos = (x, y) + + def distancexy(self, x, y): + """Gives you the distance of the agent and the given coordinate""" + return math.dist(self.pos, (x, y)) + + def distance(self, another_agent): + """Gives you the distance between the agent and another agent""" + return self.distancexy(another_agent.pos[0], another_agent.pos[1]) @property def random(self) -> Random: From ed6921f9f96f7ebd96d3cdf82084eff551ef6e0d Mon Sep 17 00:00:00 2001 From: GaelLucero Date: Fri, 8 Apr 2022 15:48:11 -0400 Subject: [PATCH 3/9] Created forward_backward function, which calculates the next position the agent will move. forward function, which moves the agent forward by specified amount. back function, which moves the agent backwards by specified amount. right function, turns the agent right by specified degree. left function, turns the agent left by specified degree. --- mesa/agent.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/mesa/agent.py b/mesa/agent.py index 0f19278efbc..9c91977becb 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -37,6 +37,29 @@ def step(self) -> None: def advance(self) -> None: pass + def forward_backward(self, amount, sign): + """Does the calculation to find the agent's next move and is used within the forward and backward functions""" + new_x = float(self.pos[0]) + sign * math.cos(self.heading * math.pi / 180) * amount + new_y = float(self.pos[1]) + sign * math.sin(self.heading * math.pi / -180) * amount + next_move = (new_x, new_y) + self.model.space.move_agent(self, next_move) + + def forward(self, amount): + """Moves the agent forward by the amount given""" + self.forward_backward(amount, 1) + + def back(self, amount): + """Moves the agent backwards from where its facing by the given amount""" + self.forward_backward(amount, -1) + + def right(self, degree): + """Turns the agent right by the given degree""" + self.heading = (self.heading - degree) % 360 + + def left(self, degree): + """Turns the agent left by the given degree""" + self.heading = (self.heading + degree) % 360 + def setxy(self, x, y): """Sets the current position to the specified x,y parameters""" self.pos = (x, y) From 6a939f50adad230fb550f6b017a8321dc6bcd30c Mon Sep 17 00:00:00 2001 From: GaelLucero Date: Fri, 8 Apr 2022 15:56:44 -0400 Subject: [PATCH 4/9] Created die function, which removes the agent from the schedule and the grid --- mesa/agent.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mesa/agent.py b/mesa/agent.py index 9c91977becb..8ceeafc5a26 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -72,6 +72,11 @@ def distance(self, another_agent): """Gives you the distance between the agent and another agent""" return self.distancexy(another_agent.pos[0], another_agent.pos[1]) + def die(self): + """Removes the agent from the schedule and the grid""" + self.model.schedule.remove(self) + self.model.space.remove_agent(self) + @property def random(self) -> Random: return self.model.random From 8bc5b5087890636058d6dcbefc205d2b57e5cded Mon Sep 17 00:00:00 2001 From: Bryan Rojas Date: Mon, 11 Apr 2022 12:10:55 -0400 Subject: [PATCH 5/9] Created face, facexy, towards, towardsxy,and random random choice functions --- mesa/agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesa/agent.py b/mesa/agent.py index 8ceeafc5a26..aacd3d6a72b 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -73,7 +73,7 @@ def distance(self, another_agent): return self.distancexy(another_agent.pos[0], another_agent.pos[1]) def die(self): - """Removes the agent from the schedule and the grid""" + """Removes the agent from the schedule and the grid """ self.model.schedule.remove(self) self.model.space.remove_agent(self) From 9f6587dbf97fc520d4c69da7ebae28725da4eeee Mon Sep 17 00:00:00 2001 From: GaelLucero Date: Tue, 12 Apr 2022 15:44:17 -0400 Subject: [PATCH 6/9] Updating die function and forward_backward function to consider error handling in regards to code reviews for commits: 6a939f50adad230fb550f6b017a8321dc6bcd30c and ed6921f9f96f7ebd96d3cdf82084eff551ef6e0d --- mesa/agent.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index aacd3d6a72b..96e91568d86 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -42,7 +42,10 @@ def forward_backward(self, amount, sign): new_x = float(self.pos[0]) + sign * math.cos(self.heading * math.pi / 180) * amount new_y = float(self.pos[1]) + sign * math.sin(self.heading * math.pi / -180) * amount next_move = (new_x, new_y) - self.model.space.move_agent(self, next_move) + try: + self.model.space.move_agent(self, next_move) + except: + print("agent.py (forward_backwards): could not move agent within self.model.space") def forward(self, amount): """Moves the agent forward by the amount given""" @@ -74,8 +77,14 @@ def distance(self, another_agent): def die(self): """Removes the agent from the schedule and the grid """ - self.model.schedule.remove(self) - self.model.space.remove_agent(self) + try: + self.model.schedule.remove(self) + except: + print("agent.py (die): could not remove agent from self.model.schedule") + try: + self.model.space.remove_agent(self) + except: + print("agent.py (die): could not remove agent from self.model.space") @property def random(self) -> Random: From d66924f9ea7a2b4f5367da56de81512da07df069 Mon Sep 17 00:00:00 2001 From: Bryan Rojas Date: Tue, 12 Apr 2022 16:21:14 -0400 Subject: [PATCH 7/9] Created face, facexy, towards, towardsxy,and random random choice functions --- mesa/agent.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/mesa/agent.py b/mesa/agent.py index 96e91568d86..f3f50dd3c08 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -86,6 +86,72 @@ def die(self): except: print("agent.py (die): could not remove agent from self.model.space") + def forward_backward(self, amount, sign): + """Does the calculation to find the agent's next move and is used within the forward and backward functions""" + new_x = float(self.pos[0]) + sign * math.cos(self.heading * math.pi / 180) * amount + new_y = float(self.pos[1]) + sign * math.sin(self.heading * math.pi / -180) * amount + next_move = (new_x, new_y) + self.model.space.move_agent(self, next_move) + + def forward(self, amount): + """Moves the agent forward by the amount given""" + self.forward_backward(amount, 1) + + def back(self, amount): + """Moves the agent backwards from where its facing by the given amount""" + self.forward_backward(amount, -1) + + def right(self, degree): + """Turns the agent right by the given degree""" + self.heading = (self.heading - degree) % 360 + + def left(self, degree): + """Turns the agent left by the given degree""" + self.heading = (self.heading + degree) % 360 + + def setxy(self, x, y): + """Sets the current position to the specified x,y parameters""" + self.pos = (x, y) + + def distancexy(self, x, y): + """Gives you the distance of the agent and the given coordinate""" + return math.dist(self.pos, (x, y)) + + def distance(self, another_agent): + """Gives you the distance between the agent and another agent""" + return self.distancexy(another_agent.pos[0], another_agent.pos[1]) + + def die(self): + """Removes the agent from the schedule and the grid""" + self.model.schedule.remove(self) + self.model.space.remove_agent(self) + + def random_choice(self, adictionary): + """Agent makes choive given dictionary values""" + return random.choices(list(adictionary.keys()), weights=adictionary.values(), k=1)[0] + + def towardsxy(self, x, y): + """Makes the agent move towards a given coordinate""" + dx = x - float(self.pos[0]) + dy = float(self.pos[1]) - y + if dx == 0: + return 90 if dy > 0 else 270 + else: + return math.degrees(math.atan2(dy, dx)) + + def towards(self, another_agent): + """Makes agent move towards another agent""" + return self.towardsxy(*another_agent.pos) + + def facexy(self, x, y): + """Makes agent face a given coordinate""" + self.heading = self.towardsxy(x, y) + + def face(self, another_agent): + """Makes agent face another agent""" + x, y = another_agent.pos + self.facexy(x, y) + @property def random(self) -> Random: return self.model.random From 08586793bfa06a536b17c15b5e7ff0f21a9a56de Mon Sep 17 00:00:00 2001 From: Bryan Rojas Date: Tue, 12 Apr 2022 16:24:43 -0400 Subject: [PATCH 8/9] removed repeated functions. --- mesa/agent.py | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/mesa/agent.py b/mesa/agent.py index f3f50dd3c08..8922727e449 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -86,46 +86,6 @@ def die(self): except: print("agent.py (die): could not remove agent from self.model.space") - def forward_backward(self, amount, sign): - """Does the calculation to find the agent's next move and is used within the forward and backward functions""" - new_x = float(self.pos[0]) + sign * math.cos(self.heading * math.pi / 180) * amount - new_y = float(self.pos[1]) + sign * math.sin(self.heading * math.pi / -180) * amount - next_move = (new_x, new_y) - self.model.space.move_agent(self, next_move) - - def forward(self, amount): - """Moves the agent forward by the amount given""" - self.forward_backward(amount, 1) - - def back(self, amount): - """Moves the agent backwards from where its facing by the given amount""" - self.forward_backward(amount, -1) - - def right(self, degree): - """Turns the agent right by the given degree""" - self.heading = (self.heading - degree) % 360 - - def left(self, degree): - """Turns the agent left by the given degree""" - self.heading = (self.heading + degree) % 360 - - def setxy(self, x, y): - """Sets the current position to the specified x,y parameters""" - self.pos = (x, y) - - def distancexy(self, x, y): - """Gives you the distance of the agent and the given coordinate""" - return math.dist(self.pos, (x, y)) - - def distance(self, another_agent): - """Gives you the distance between the agent and another agent""" - return self.distancexy(another_agent.pos[0], another_agent.pos[1]) - - def die(self): - """Removes the agent from the schedule and the grid""" - self.model.schedule.remove(self) - self.model.space.remove_agent(self) - def random_choice(self, adictionary): """Agent makes choive given dictionary values""" return random.choices(list(adictionary.keys()), weights=adictionary.values(), k=1)[0] From 8a2b3feba690b8f6568ab0592cd57c6073b09aaf Mon Sep 17 00:00:00 2001 From: GaelLucero Date: Fri, 15 Apr 2022 22:19:03 -0400 Subject: [PATCH 9/9] Updating function names per comments in pull request #1278. Adding background image capabilities to new visualization module SimpleContinousModule.py and added various shapes including rectangle, circle, default, triangle, star, smile, pentagon, arrow, plane, and ant. --- mesa/agent.py | 30 +- .../modules/SimpleContinuousModule.py | 34 ++ .../modules/simple_continuous_canvas.js | 332 ++++++++++++++++++ 3 files changed, 381 insertions(+), 15 deletions(-) create mode 100644 mesa/visualization/modules/SimpleContinuousModule.py create mode 100644 mesa/visualization/modules/simple_continuous_canvas.js diff --git a/mesa/agent.py b/mesa/agent.py index 8922727e449..08937bd112c 100644 --- a/mesa/agent.py +++ b/mesa/agent.py @@ -37,29 +37,29 @@ def step(self) -> None: def advance(self) -> None: pass - def forward_backward(self, amount, sign): + def move_forward_or_backward(self, amount, sign): """Does the calculation to find the agent's next move and is used within the forward and backward functions""" new_x = float(self.pos[0]) + sign * math.cos(self.heading * math.pi / 180) * amount new_y = float(self.pos[1]) + sign * math.sin(self.heading * math.pi / -180) * amount - next_move = (new_x, new_y) + next_pos = (new_x, new_y) try: - self.model.space.move_agent(self, next_move) + self.model.space.move_agent(self, next_pos) except: print("agent.py (forward_backwards): could not move agent within self.model.space") - def forward(self, amount): + def move_forward(self, amount): """Moves the agent forward by the amount given""" - self.forward_backward(amount, 1) + self.move_forward_or_backward(amount, 1) - def back(self, amount): + def move_backward(self, amount): """Moves the agent backwards from where its facing by the given amount""" - self.forward_backward(amount, -1) + self.move_forward_or_backward(amount, -1) - def right(self, degree): + def turn_right(self, degree): """Turns the agent right by the given degree""" self.heading = (self.heading - degree) % 360 - def left(self, degree): + def turn_left(self, degree): """Turns the agent left by the given degree""" self.heading = (self.heading + degree) % 360 @@ -67,6 +67,10 @@ def setxy(self, x, y): """Sets the current position to the specified x,y parameters""" self.pos = (x, y) + def set_pos(self, apos): + """Sets the current position to the specified pos parameter""" + self.pos = apos + def distancexy(self, x, y): """Gives you the distance of the agent and the given coordinate""" return math.dist(self.pos, (x, y)) @@ -86,12 +90,8 @@ def die(self): except: print("agent.py (die): could not remove agent from self.model.space") - def random_choice(self, adictionary): - """Agent makes choive given dictionary values""" - return random.choices(list(adictionary.keys()), weights=adictionary.values(), k=1)[0] - def towardsxy(self, x, y): - """Makes the agent move towards a given coordinate""" + """Calculates angle between a given coordinate and horizon as if the current position is the origin""" dx = x - float(self.pos[0]) dy = float(self.pos[1]) - y if dx == 0: @@ -100,7 +100,7 @@ def towardsxy(self, x, y): return math.degrees(math.atan2(dy, dx)) def towards(self, another_agent): - """Makes agent move towards another agent""" + """Calculates angle between an agent and horizon as if the current position is the origin""" return self.towardsxy(*another_agent.pos) def facexy(self, x, y): diff --git a/mesa/visualization/modules/SimpleContinuousModule.py b/mesa/visualization/modules/SimpleContinuousModule.py new file mode 100644 index 00000000000..7898dd07315 --- /dev/null +++ b/mesa/visualization/modules/SimpleContinuousModule.py @@ -0,0 +1,34 @@ +from mesa.visualization.ModularVisualization import VisualizationElement + + +class SimpleCanvas(VisualizationElement): + local_includes = ["simple_continuous_canvas.js"] + portrayal_method = None + canvas_height = 500 + canvas_width = 500 + + def __init__(self, portrayal_method, canvas_height=500, canvas_width=500, background_src=None): + """ + Instantiate a new SimpleCanvas + """ + self.portrayal_method = portrayal_method + self.canvas_height = canvas_height + self.canvas_width = canvas_width + self.background_src = background_src + new_element = "new Simple_Continuous_Module({}, {}, {})".format( + self.canvas_width, self.canvas_height, "'" + self.background_src + "'" if self.background_src != None else "null" + ) + self.js_code = "elements.push(" + new_element + ");" + + def render(self, model): + space_state = [] + for obj in model.schedule.agents: + portrayal = self.portrayal_method(obj) + x, y = obj.pos + x = (x - model.space.x_min) / (model.space.x_max - model.space.x_min) + y = (y - model.space.y_min) / (model.space.y_max - model.space.y_min) + portrayal["x"] = x + portrayal["y"] = y + portrayal["heading"] = obj.heading + space_state.append(portrayal) + return space_state \ No newline at end of file diff --git a/mesa/visualization/modules/simple_continuous_canvas.js b/mesa/visualization/modules/simple_continuous_canvas.js new file mode 100644 index 00000000000..4d50486a8cc --- /dev/null +++ b/mesa/visualization/modules/simple_continuous_canvas.js @@ -0,0 +1,332 @@ +var ContinuousVisualization = function(height, width, context, background_src=null) { + var height = height; + var width = width; + var context = context; + var background = new Image(); + var background_src = background_src; + + this.draw = function(objects) { // https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes + for (var i in objects) { + var p = objects[i]; + if (p.Shape == "rectangle") + this.drawRectangle(p.x, p.y, p.w, p.h, p.Color, p.Filled); + if (p.Shape == "circle"){ + this.drawCircle(p.x, p.y, p.r, p.Color, false); + this.drawRadius(p.x, p.y, p.r, p.heading, p.Color) + } + if (p.Shape == "default"){ + this.drawDefault(p.x, p.y, p.r, p.heading, p.Color) + } + if(p.Shape == "triangle"){ + this.drawTriangle(p.x, p.y, p.r, p.heading, p.Color) + } + if(p.Shape == "star"){ + this.drawStar(p.x, p.y, p.r, p.heading, p.Color) + } + if(p.Shape == "smile"){ + this.drawSmileFace(p.x, p.y, p.r, p.heading, p.Color) + } + if(p.Shape == "pentagon"){ + this.drawPentagon(p.x, p.y, p.r, p.heading, p.Color) + } + if(p.Shape == "arrow"){ + this.drawArrow(p.x, p.y, p.r, p.heading, p.Color) + } + if(p.Shape == "plane"){ + this.drawPlane(p.x, p.y, p.r, p.heading, p.Color) + } + if (p.Shape == "ant"){ + this.drawAnt(p.x, p.y, p.r, p.heading, p.Color) + } + } + }; + this.drawAnt = function(x,y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //put points into here: + context.arc(0, 0, r/6, Math.PI/2, 5 * Math.PI/2, false); + context.moveTo((r/-5), 0); + context.arc(r/-5, 0, r/5, Math.PI/2, 5 * Math.PI/2, false); + context.moveTo((r/5),0); + context.arc((r/5),0, r/6, Math.PI/2, 5 * Math.PI/2, false); + context.moveTo((r/4), (r/10)); + context.lineTo((r/2), (r/4)); + context.moveTo((r/4), (r/-10)); + context.lineTo((r/2), (r/-4)); + //put points above here + context.fill(); + context.stroke(); + context.restore(); + }; + this.drawPlane = function(x, y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //add points bellow here + + context.moveTo(r, 0) + context.lineTo((r*3/4), (r/8)) //1 + context.lineTo((r*4/6), (r/8)) //2 + context.lineTo((r*2/5), (r/2)) //3 + context.lineTo((r*2/7), (r/2)) //4 + context.lineTo((r*2/7), (r/8)) //5 + context.lineTo((r/6), (r/12)) //6 + context.lineTo((r/12), (r/6)) //7 + context.lineTo((r/8), 0) //8 + context.lineTo((r/12), (-r/6)) //9 + context.lineTo((r/6), (-r/12)) + context.lineTo((r*2/7), (-r/8)) + context.lineTo((r*2/7), (-r/2)) + context.lineTo((r*2/5), (-r/2)) + context.lineTo((r*4/6), (-r/8)) + context.lineTo((r*3/4), (-r/8)) + + //add points above here + context.fill(); + context.stroke(); + context.restore(); + } + this.drawArrow = function(x, y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //place coordinates bellow + context.moveTo(r, 0) + context.lineTo((r*2/3), (r/4)) + context.lineTo((r*2/3), (r/11)) + context.lineTo((r/3), (r/11)) + context.lineTo((r/3), (-r/11)) + context.lineTo((r*2/3),(-r/11)) + context.lineTo((r*2/3),(-r/4)) + context.fill(); + context.stroke(); + context.restore(); + } + //feedback on how pentagon looks + this.drawPentagon = function(x, y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + + //place bellow here + context.moveTo(r, 0) + context.lineTo((r/2), (-r*13/15)) + context.lineTo((-r*8/11), (-r*8/13)) + context.lineTo((-r*8/11), (r*8/13)) + context.lineTo((r/2),(r*13/15)) + //points above here + + context.fill(); + context.stroke(); + context.restore(); + }; + //feedback on how smileyface looks + this.drawSmileFace = function(x, y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //put points into here: + context.arc(0, 0, r/2, Math.PI/2, 5 * Math.PI/2, false); //Outer layer + context.moveTo(0, (r/3)) + context.arc(0, 0, r/3, Math.PI/2, 3 * Math.PI/2, true); //Smile + context.moveTo(0, (r/-6)); // x = r/4 && y = (r * -0.416) + context.arc(r/-6, r/-6, r/8, 0, Math.PI * 2, true) // left eye + context.moveTo(0, (r/6)) + context.arc(r/-6, r/6, r/8, 0, Math.PI * 2, true) // right eye + //put points above here + context.fill(); + //context.stroke(); + context.restore(); + } + //feedback on how star looks + this.drawStar = function(x, y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //put points into here: + context.moveTo((r/2),0) + context.lineTo((r/5), (r/10)) + context.lineTo((r/5), (r/2)) // extended arm + context.lineTo((r/-20), (r/6)) + context.lineTo((r/-3), (r/4)) + context.lineTo((r/-6), 0) + context.lineTo((r/-3), (r/-4)) + context.lineTo((r/-20), (r/-6)) + context.lineTo((r/5), (r/-2)) // extended arm + //context.lineTo((r/-10), (r/5)) + context.lineTo((r/5), (r/-10)) + context.lineTo((r/2),0) + //put points above here + context.fill(); + context.stroke(); + context.restore(); + }; + this.drawTriangle = function(x,y, radius, heading, color){ + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //put points into here: + context.moveTo((r/2), 0) + context.lineTo((r/-3), (r/-3)) + context.lineTo((r/-3), (r/3)) + //put points above here + context.fill(); + context.restore(); + }; + this.drawDefault = function(x,y, radius, heading, color){ + //p1 (r,0) + //p2 (-r/2, r/4) + //p3 (0,0) + //p4 (-r/2, -r/4) + var cx = x * width; + var cy = y * height; + var r = radius; + context.save(); + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate(cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + //put points into here: + context.moveTo((r/2) , 0 ); + context.lineTo((r/-3) , (r/4)); + context.lineTo(0 ,0 ); + context.lineTo((r/-3) , (r/-4)); + //put points above here + context.fill(); + context.restore(); + }; + this.drawCircle = function(x, y, radius, color, fill) { + var cx = x * width; + var cy = y * height; + var r = radius; + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.arc(cx, cy, r, 0, Math.PI * 2, false); + context.closePath(); + context.stroke(); + if (fill) { + context.fillStyle = color; + context.fill(); + } + }; + this.drawRadius = function(x, y, radius, heading, color) { + var cx = x * width; + var cy = y * height; + var r = radius; + context.save() + context.strokeStyle = color; + context.fillStyle = color; + context.beginPath(); + context.translate( cx, cy); + context.scale(1,-1); + context.rotate(heading*Math.PI/180); + context.fillRect(0, 0, 0 + r, 2); + context.strokeStyle = color; + context.stroke(); + context.restore(); + }; + + this.drawRectangle = function(x, y, w, h, color, fill) { + context.beginPath(); + var dx = w * width; + var dy = h * height; + // Keep the drawing centered: + var x0 = (x*width) - 0.5*dx; + var y0 = (y*height) - 0.5*dy; + context.strokeStyle = color; + context.fillStyle = color; + if (fill) + context.fillRect(x0, y0, dx, dy); + else + context.strokeRect(x0, y0, dx, dy); + }; + + this.resetCanvas = function() { + context.clearRect(0, 0, height, width); + context.beginPath(); + if(background_src != null){ + this.drawBackground(); + } + }; + this.drawBackground = function(){ + context.globalAlpha = .5; + background.src = background_src; + context.drawImage(background,0,0, 500, 500); + context.globalAlpha = 1; + } +}; + +var Simple_Continuous_Module = function(canvas_width, canvas_height, background_src) { + // Create the element + // ------------------ + // Create the tag: + var canvas_tag = "