From 9c9f35753489cba5a61816104ac294857be20941 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 29 Apr 2011 20:35:20 +0200 Subject: host/simu: transpose transformation matrix, reverse transformation order This is better because transformations can be built incrementally from the container to the contained. This use the same semantic as OpenGL. --- host/inter/inter.py | 2 +- host/simu/inter/inter.py | 2 +- host/simu/inter/test/test_drawable.py | 4 ++-- host/simu/model/distance_sensor.py | 2 +- host/simu/robots/aquajim/model/sorter.py | 2 +- host/simu/robots/aquajim/view/robot.py | 2 +- host/simu/robots/giboulee/view/robot.py | 2 +- host/simu/robots/marcel/model/loader.py | 4 ++-- host/simu/robots/marcel/view/loader.py | 2 +- host/simu/robots/marcel/view/robot.py | 2 +- host/simu/utils/trans_matrix.py | 31 ++++++++++++++++++------------- host/simu/view/table_eurobot2009.py | 2 +- 12 files changed, 31 insertions(+), 26 deletions(-) diff --git a/host/inter/inter.py b/host/inter/inter.py index 3f1effd4..f097f955 100644 --- a/host/inter/inter.py +++ b/host/inter/inter.py @@ -33,8 +33,8 @@ class Robot (Drawable): def draw (self): self.reset () if self.angle is not None: - self.trans_rotate (self.angle) self.trans_translate (self.pos) + self.trans_rotate (self.angle) self.draw_polygon ((115, 30), (170, 85), (150, 127), (130, 145), (-25, 200), (-70, 200), (-70, -200), (-25, -200), (130, -145), (150, -127), (170, -85), (115, -30)) diff --git a/host/simu/inter/inter.py b/host/simu/inter/inter.py index b8a889e5..8623885f 100644 --- a/host/simu/inter/inter.py +++ b/host/simu/inter/inter.py @@ -58,8 +58,8 @@ class ActuatorView (DrawableCanvas): self.resize (1, self.size, 0, self.size / 2) self.configure (width = self.UNIT, height = self.UNIT * self.size) d = Drawable (self) - d.trans_scale (1.0 / width) d.trans_translate ((0, - self.size + ratio / 2)) + d.trans_scale (1.0 / width) return d class Inter (Frame): diff --git a/host/simu/inter/test/test_drawable.py b/host/simu/inter/test/test_drawable.py index b977d36e..a9c1bfef 100644 --- a/host/simu/inter/test/test_drawable.py +++ b/host/simu/inter/test/test_drawable.py @@ -49,9 +49,9 @@ class App (DrawableCanvas): # Real user should reset at each redraw. self.after (500, self.animate) self.test.draw () - self.test.trans_rotate (-pi/12) - self.test.trans_translate ((10, 10)) self.test.trans_scale (1.05) + self.test.trans_translate ((10, 10)) + self.test.trans_rotate (-pi/12) self.i += 1 if self.i == 10: self.test.reset () diff --git a/host/simu/model/distance_sensor.py b/host/simu/model/distance_sensor.py index 3dc83f45..bdc8531d 100644 --- a/host/simu/model/distance_sensor.py +++ b/host/simu/model/distance_sensor.py @@ -46,8 +46,8 @@ class DistanceSensor: if i.pos is None: self.distance = None return - m.rotate (i.angle) m.translate (i.pos) + m.rotate (i.angle) pos, target = m.apply (pos, target) # Find intersection. i = self.table.intersect (pos, target, level = self.level, diff --git a/host/simu/robots/aquajim/model/sorter.py b/host/simu/robots/aquajim/model/sorter.py index e7b69761..93ff5e2a 100644 --- a/host/simu/robots/aquajim/model/sorter.py +++ b/host/simu/robots/aquajim/model/sorter.py @@ -58,8 +58,8 @@ class Sorter (Observable): for i in self.into: if i.pos is None: return None - m.rotate (i.angle) m.translate (i.pos) + m.rotate (i.angle) return m.apply (pos) def __arm_motor_notified (self): diff --git a/host/simu/robots/aquajim/view/robot.py b/host/simu/robots/aquajim/view/robot.py index ad613bba..aefe2170 100644 --- a/host/simu/robots/aquajim/view/robot.py +++ b/host/simu/robots/aquajim/view/robot.py @@ -42,8 +42,8 @@ class Robot (simu.inter.drawable.Drawable): """Draw the robot.""" self.reset () if self.pos is not None: - self.trans_rotate (self.angle) self.trans_translate (self.pos) + self.trans_rotate (self.angle) # Draw robot body. self.draw_polygon ((150, 155), (-90, 155), (-150, 70), (-150, -70), (-90, -155), (150, -155)) diff --git a/host/simu/robots/giboulee/view/robot.py b/host/simu/robots/giboulee/view/robot.py index ab1ffc6d..42ebe6fb 100644 --- a/host/simu/robots/giboulee/view/robot.py +++ b/host/simu/robots/giboulee/view/robot.py @@ -42,8 +42,8 @@ class Robot (simu.inter.drawable.Drawable): """Draw the robot.""" self.reset () if self.pos is not None: - self.trans_rotate (self.angle) self.trans_translate (self.pos) + self.trans_rotate (self.angle) # Draw robot body. self.draw_polygon ((115, 30), (170, 85), (150, 127), (130, 145), (-25, 200), (-70, 200), (-70, -200), (-25, -200), diff --git a/host/simu/robots/marcel/model/loader.py b/host/simu/robots/marcel/model/loader.py index 0270ce79..ae1caa7d 100644 --- a/host/simu/robots/marcel/model/loader.py +++ b/host/simu/robots/marcel/model/loader.py @@ -159,8 +159,8 @@ class Loader (Observable): # If gate is high, drop elements. if self.load and self.gate_angle > self.GATE_STROKE / 2: m = TransMatrix () - m.rotate (self.robot_position.angle) m.translate (self.robot_position.pos) + m.rotate (self.robot_position.angle) pos = m.apply ((-250, 0)) for e in self.load: e.pos = pos @@ -177,9 +177,9 @@ class Loader (Observable): return elements # Matrix to transform an obstacle position into robot coordinates. m = TransMatrix () + m.rotate (-self.robot_position.angle) m.translate ((-self.robot_position.pos[0], -self.robot_position.pos[1])) - m.rotate (-self.robot_position.angle) # Look up elements. # This could be used if clamp blocking is handled or elements are # pushed: diff --git a/host/simu/robots/marcel/view/loader.py b/host/simu/robots/marcel/view/loader.py index 5bda5d5b..d4ed336e 100644 --- a/host/simu/robots/marcel/view/loader.py +++ b/host/simu/robots/marcel/view/loader.py @@ -67,8 +67,8 @@ class Loader (Drawable): (300, 25 + 25 * i + (150 - 20 * i) * ratio)) if self.model.elevator_height is not None: self.trans_identity () - self.trans_rotate (-self.model.elevator_angle) self.trans_translate ((-100, -100 + self.model.elevator_height)) + self.trans_rotate (-self.model.elevator_angle) # Draw clamp load. if self.model.clamp_load: elements = self.model.clamp_load diff --git a/host/simu/robots/marcel/view/robot.py b/host/simu/robots/marcel/view/robot.py index 4e2135f2..67d505a2 100644 --- a/host/simu/robots/marcel/view/robot.py +++ b/host/simu/robots/marcel/view/robot.py @@ -52,8 +52,8 @@ class Robot (simu.inter.drawable.Drawable): """Draw the robot.""" self.reset () if self.pos is not None: - self.trans_rotate (self.angle) self.trans_translate (self.pos) + self.trans_rotate (self.angle) # Draw robot body. self.draw_polygon ((120, 155), (-95, 155), (-160, 90), (-160, -90), (-95, -155), (120, -155)) diff --git a/host/simu/utils/trans_matrix.py b/host/simu/utils/trans_matrix.py index 12bc7b35..1b582e1b 100644 --- a/host/simu/utils/trans_matrix.py +++ b/host/simu/utils/trans_matrix.py @@ -27,8 +27,13 @@ from math import sin, cos, sqrt, atan2 class TransMatrix: """Define a matrix to be used for transformations on the plane. - This is a "special" kind of matrix, because the last column is omitted as - it is always (0, 0, 1).""" + This is a "special" kind of matrix, because the last line is omitted as + it is always (0, 0, 1). + + First index is column, last index is line. + + Transformations are done from the last added to the first added, so that + it can be incrementally constructed for objects contained in others.""" IDENTITY = ((1, 0), (0, 1), (0, 0)) @@ -65,7 +70,7 @@ class TransMatrix: >>> from math import pi >>> a = TransMatrix () >>> a.rotate (pi / 3); a # doctest: +ELLIPSIS - ((0.5..., 0.866...), (-0.866..., 0.5...), (0.0, 0.0)) + ((0.5..., 0.866...), (-0.866..., 0.5...), (0, 0)) """ s = sin (angle) c = cos (angle) @@ -98,17 +103,17 @@ class TransMatrix: >>> a = TransMatrix ((1, 0), (0, 1), (1, 0)) >>> b = TransMatrix ((0, 1), (1, 0), (0, 1)) >>> a *= b; a - ((0, 1), (1, 0), (0, 2)) + ((0, 1), (1, 0), (1, 1)) """ s = self.matrix o = other.matrix self.matrix = ( - (s[0][0] * o[0][0] + s[0][1] * o[1][0], - s[0][0] * o[0][1] + s[0][1] * o[1][1]), - (s[1][0] * o[0][0] + s[1][1] * o[1][0], - s[1][0] * o[0][1] + s[1][1] * o[1][1]), - (s[2][0] * o[0][0] + s[2][1] * o[1][0] + o[2][0], - s[2][0] * o[0][1] + s[2][1] * o[1][1] + o[2][1])) + (s[0][0] * o[0][0] + s[1][0] * o[0][1], + s[0][1] * o[0][0] + s[1][1] * o[0][1]), + (s[0][0] * o[1][0] + s[1][0] * o[1][1], + s[0][1] * o[1][0] + s[1][1] * o[1][1]), + (s[0][0] * o[2][0] + s[1][0] * o[2][1] + s[2][0], + s[0][1] * o[2][0] + s[1][1] * o[2][1] + s[2][1])) return self def apply (self, *args): @@ -121,9 +126,9 @@ class TransMatrix: ((20, 40), (21, 42)) """ r = tuple ( - (i[0] * self.matrix[0][0] + i[1] * self.matrix[1][0] + (self.matrix[0][0] * i[0] + self.matrix[1][0] * i[1] + self.matrix[2][0], - i[0] * self.matrix[0][1] + i[1] * self.matrix[1][1] + self.matrix[0][1] * i[0] + self.matrix[1][1] * i[1] + self.matrix[2][1]) for i in args) if len (args) == 1: @@ -172,7 +177,7 @@ class TransMatrix: ((1, 0), (0, 1), (2, 3)) >>> a.push () >>> a.scale (2); a - ((2, 0), (0, 2), (4, 6)) + ((2, 0), (0, 2), (2, 3)) >>> a.pop () >>> a ((1, 0), (0, 1), (2, 3)) diff --git a/host/simu/view/table_eurobot2009.py b/host/simu/view/table_eurobot2009.py index 5e2d6db5..282b25a5 100644 --- a/host/simu/view/table_eurobot2009.py +++ b/host/simu/view/table_eurobot2009.py @@ -113,8 +113,8 @@ class Table (Drawable): ((3000 - 40, 1050 + ds), pi, GREEN), ): dtm = TransMatrix () - dtm.rotate (dangle) dtm.translate (dpos) + dtm.rotate (dangle) if dpos[1] == 40: a = 55 else: -- cgit v1.2.3