changeset 27:44689029a86f

updated segmentIntersection and other
author Nicolas Saunier <nico@confins.net>
date Sat, 05 Dec 2009 15:40:28 -0500
parents 54d9cb0c902b
children 9ae709a2e8d0
files python/moving.py python/utils.py
diffstat 2 files changed, 64 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/python/moving.py	Sat Dec 05 12:31:28 2009 -0500
+++ b/python/moving.py	Sat Dec 05 15:40:28 2009 -0500
@@ -25,17 +25,6 @@
     def __str__(self):
         return '%d %d'%(self.first, self.last)
 
-    def __iter__(self):
-        self.iterInstantNum = 0
-        return self
-
-    def next(self):
-        if self.iterInstantNum >= self.length():
-            raise StopIteration
-        else:
-            self.iterInstantNum += 1
-            return self.first+self.iterInstantNum
-
     def empty(self):
         '''
         >>> Interval().empty()
@@ -75,12 +64,28 @@
         '''Largest interval comprising self and interval2'''
         return TimeInterval(max(self.first, interval2.first), min(self.last, interval2.last))
 
-def TimeInterval(Interval):
+
+class TimeInterval(Interval):
     '''Temporal interval'''
 
     def __init__(self, first=0, last=-1):
         Interval.__init__(self, first, last, False)
 
+    def __getitem__(self, i):
+        if not self.empty():
+            return self.first+i
+
+    def __iter__(self):
+        self.iterInstantNum = 0
+        return self
+
+    def next(self):
+        if self.iterInstantNum >= self.length():
+            raise StopIteration
+        else:
+            self.iterInstantNum += 1
+            return self[self.iterInstantNum]
+
     def length(self):
         '''Returns the length of the interval
         
@@ -232,22 +237,19 @@
         '''Returns the instant(s) the object passes from one side of the segment to the other
         empty list if not'''
         instants = []
-        lane = [[p1[0],p2[0]], [p1[1],p2[1]]]
-
-        # refaire tout en points, marche pas
-        # self.positions[i] self.positions[i+1]
 
         for i in xrange(self.length()-1):
-            p = utils.segmentIntersection([self.positions[0][i:i+1],self.positions[1][i:i+1]], lane)
-            if p: # interpolate the instant
-                if self.positions[0][i] != self.positions[0][i+1]:
-                    ratio = (p[0]-self.positions[0][i])/(self.positions[0][i+1]-self.positions[0][i])
-                elif self.positions[1][i] != self.positions[1][i+1]:
-                    ratio = (p[1]-self.positions[1][i])/(self.positions[1][i+1]-self.positions[1][i])
+            p = utils.segmentIntersection(self.positions[i], self.positions[i+1], p1, p2)
+            if p:
+                if self.positions[i].x != self.positions[i+1].x:
+                    ratio = (p.x-self.positions[i].x)/(self.positions[i+1].x-self.positions[i].x)
+                elif self.positions[i].y != self.positions[i+1].y:
+                    ratio = (p.y-self.positions[i].y)/(self.positions[i+1].y-self.positions[i].y)
                 else:
                     ratio = 0
                 instants.append(self.timeInterval[i]*(1-ratio)+ratio*self.timeInterval[i+1])
         return instants
+
     # def computeVelocities(self):
 
 # need for a class representing the indicators, their units, how to print them in graphs...
--- a/python/utils.py	Sat Dec 05 12:31:28 2009 -0500
+++ b/python/utils.py	Sat Dec 05 15:40:28 2009 -0500
@@ -4,49 +4,54 @@
 #from numpy import *
 #from pylab import *
 
+from moving import Point,Interval
+
 __metaclass__ = type
 
 commentChar = '#';
 
-# maths
+#########################
+# maths section
+#########################
 
-def segmentIntersection(s1, s2):
-    '''Returns the intersecting point, None otherwise
-    format for a segment is [[x1, x2], [y1,y2]]
+def segmentIntersection(p1, p2, p3, p4):
+    '''Returns the intersecting point of the segments [p1, p2] and [p3, p4], None otherwise
     
-    >>> segmentIntersection([[0, 1], [0,1]], [[0, 1], [1,2]])
-    >>> segmentIntersection([[0, 1], [1,0]], [[0, 1], [2,1]])
-    >>> segmentIntersection([[0, 2], [0,0]], [[1, 1], [-1,1]])
-    [1.0, 0.0]
-    >>> segmentIntersection([[0, 2], [0,0]], [[1, 1], [1,2]])
+    >>> segmentIntersection(Point(0,0),Point(1,1), Point(0,1), Point(1,2))
+    >>> segmentIntersection(Point(0,1),Point(1,0), Point(0,2), Point(2,1))
+    >>> segmentIntersection(Point(0,0),Point(2,0), Point(1,-1),Point(1,1))
+    (1.000000,0.000000)
+    >>> segmentIntersection(Point(0,1),Point(2,0),Point(1,1),Point(1,2))
     '''
     from numpy import matrix
     from numpy.linalg import linalg, det
 
-    ds1 = [s1[0][1]-s1[0][0], s1[1][1]-s1[1][0]]
-    ds2 = [s2[0][1]-s2[0][0], s2[1][1]-s2[1][0]]
+    dp1 = p2-p1#[s1[0][1]-s1[0][0], s1[1][1]-s1[1][0]]
+    dp2 = p4-p3#[s2[0][1]-s2[0][0], s2[1][1]-s2[1][0]]
 
-    A = matrix([[ds1[1], -ds1[0]],
-                [ds2[1], -ds2[0]]])
-    B = matrix([[ds1[1]*s1[0][0]-ds1[0]*s1[1][0]],
-                [ds2[1]*s2[0][0]-ds2[0]*s2[1][0]]])
+    A = matrix([[dp1.y, -dp1.x],
+                [dp2.y, -dp2.x]])
+    B = matrix([[dp1.y*p1.x-dp1.x*p1.y],
+                [dp2.y*p3.x-dp2.x*p3.y]])
 
     if linalg.det(A) == 0:#crossProduct(ds1, ds2) == 0:
         return None
     else:
         intersection = linalg.solve(A,B)
-        if (intersection[0,0] >= s1[0][0] and intersection[0,0] <= s1[0][1]
-            and intersection[0,0] >= s2[0][0] and intersection[0,0] <= s2[0][1]
-            and intersection[1,0] >= s1[1][0] and intersection[1,0] <= s1[1][1]
-            and intersection[1,0] >= s2[1][0] and intersection[1,0] <= s2[1][1]):
-            return [intersection[0,0], intersection[1,0]]
+        if (Interval(p1.x, p2.x, True).contains(intersection[0,0])
+            and Interval(p3.x, p4.x, True).contains(intersection[0,0])
+            and Interval(p1.y, p2.y, True).contains(intersection[1,0])
+            and Interval(p3.y, p4.y, True).contains(intersection[1,0])):
+            return Point(intersection[0,0], intersection[1,0])
         else:
             return None
 
 def crossProduct(l1, l2):
     return l1[0]*l2[1]-l1[1]*l2[0]
 
-# file I/O
+#########################
+# file I/O section
+#########################
 
 def openCheck(filename, option = 'r', quit = False):
     '''Open file filename in read mode by default
@@ -103,6 +108,7 @@
 
 def invertHomography(homography):
     'Returns an inverted homography'
+    from numpy.linalg.linalg import inv
     invH = inv(homography)
     invH /= invH[2,2]
     return invH
@@ -122,8 +128,19 @@
         projected = p
     return projected[:2]
 
-def printPoint(x,y):
-    return '(%f,%f)'%(x,y)
+def projectTrajectory(homography, trajectory):
+    '''Projects a series of points in the format
+    [[x1, x2, ...],
+    [y1, y2, ...]]
+
+    Warning: not optimized, calls project()'''
+    projected = [[],[]]
+    for x, y in zip(trajectory[0], trajectory[1]):
+        p = [x,y]
+        pp = project(homography, p)
+        projected[0].append(pp[0])
+        projected[1].append(pp[1])
+    return projected
 
 def plotPolygon(poly, options = ''):
     from numpy.core.multiarray import array