Package libavg :: Module mathutil

Source Code for Module libavg.mathutil

  1  # libavg - Media Playback Engine. 
  2  # Copyright (C) 2003-2008 Ulrich von Zadow 
  3  # 
  4  # This library is free software; you can redistribute it and/or 
  5  # modify it under the terms of the GNU Lesser General Public 
  6  # License as published by the Free Software Foundation; either 
  7  # version 2 of the License, or (at your option) any later version. 
  8  # 
  9  # This library is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 12  # Lesser General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU Lesser General Public 
 15  # License along with this library; if not, write to the Free Software 
 16  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 17  # 
 18  # Current versions can be found at www.libavg.de 
 19  # 
 20  # Original author of this file is Martin Heistermann <mh at sponc dot de> 
 21  # 
 22   
 23  import math 
 24  from libavg import Point2D 
 25   
26 -def getAngle(p1, p2):
27 vec = p2 - p1 28 res = math.atan2(vec.y, vec.x) 29 if res < 0: 30 res += math.pi * 2 31 return res
32
33 -def getDistance (p, q):
34 return math.sqrt((p.x-q.x)**2 + (p.y-q.y)**2)
35
36 -def getDistSquared (p, q):
37 return (p.x-q.x)**2 + (p.y-q.y)**2
38
39 -def getScaleToSize ((width, height), (max_width, max_height)):
40 if width < max_width: 41 height = height * (float(max_width) / width) 42 width = max_width 43 elif height > max_height: 44 width = width * (float(max_height) / height) 45 height = max_height 46 return getScaledDim((width, height), (max_width, max_height))
47
48 -def getScaledDim (size, max = None, min = None):
49 width, height = size 50 if width == 0 or height == 0: 51 return size 52 53 if max: 54 max = Point2D(max) 55 assert (max.x > 0 and max.y > 0) 56 if width > max.x: 57 height = height * (max.x / width) 58 width = max.x 59 if height > max.y: 60 width = width * (max.y / height) 61 height = max.y 62 63 if min: 64 min = Point2D(min) 65 assert (min.x > 0 and min.y > 0) 66 if width < min.x: 67 height = height * (min.x / width) 68 width = min.x 69 if height < min.y: 70 width = width * (min.y / height) 71 height = min.y 72 73 return Point2D(width, height)
74 75
76 -class EquationNotSolvable (Exception):
77 pass
78 -class EquationSingular (Exception):
79 pass
80
81 -def gauss_jordan(m, eps = 1.0/(10**10)):
82 """Puts given matrix (2D array) into the Reduced Row Echelon Form. 83 Returns True if successful, False if 'm' is singular. 84 NOTE: make sure all the matrix items support fractions! Int matrix will NOT work! 85 Written by Jarno Elonen in April 2005, released into Public Domain 86 http://elonen.iki.fi/code/misc-notes/affine-fit/index.html""" 87 (h, w) = (len(m), len(m[0])) 88 for y in range(0,h): 89 maxrow = y 90 for y2 in range(y+1, h): # Find max pivot 91 if abs(m[y2][y]) > abs(m[maxrow][y]): 92 maxrow = y2 93 (m[y], m[maxrow]) = (m[maxrow], m[y]) 94 if abs(m[y][y]) <= eps: # Singular? 95 raise EquationSingular 96 for y2 in range(y+1, h): # Eliminate column y 97 c = m[y2][y] / m[y][y] 98 for x in range(y, w): 99 m[y2][x] -= m[y][x] * c 100 for y in range(h-1, 0-1, -1): # Backsubstitute 101 c = m[y][y] 102 for y2 in range(0,y): 103 for x in range(w-1, y-1, -1): 104 m[y2][x] -= m[y][x] * m[y2][y] / c 105 m[y][y] /= c 106 for x in range(h, w): # Normalize row y 107 m[y][x] /= c 108 return m
109 110
111 -def solveEquationMatrix(_matrix, eps = 1.0/(10**10)):
112 matrix=[] 113 for coefficients, res in _matrix: 114 newrow = map(float, coefficients + (res,)) 115 matrix.append(newrow) 116 matrix = gauss_jordan (matrix) 117 res=[] 118 for col in xrange(len(matrix[0])-1): 119 rows = filter(lambda row: row[col] >= eps, matrix) 120 if len(rows)!=1: 121 raise EquationNotSolvable 122 res.append (rows[0][-1]) 123 124 return res
125 126
127 -def getOffsetForMovedPivot(oldPivot, newPivot, angle):
128 oldPos = Point2D(0,0).getRotated(angle, oldPivot) 129 newPos = Point2D(0,0).getRotated(angle, newPivot) 130 return oldPos - newPos
131
132 -def isNaN(x):
133 return (not(x<=0) and not(x>=0))
134
135 -def sgn (x):
136 if x<0: 137 return -1 138 elif x==0: 139 return 0 140 else: 141 return 1
142
143 -class MovingAverage:
144 """ 145 Moving average implementation. 146 Example: 147 ma = MovingAverage(20) 148 print ma(2) 149 print ma(3) 150 print ma(10) 151 """
152 - def __init__(self, points):
153 self.__points = points 154 self.__values = []
155
156 - def __appendValue(self, value):
157 self.__values = (self.__values + [value])[-self.__points:]
158
159 - def __getAverage(self):
160 sum = reduce(lambda a,b:a+b, self.__values) 161 return float(sum) / len(self.__values)
162
163 - def __call__(self, value):
164 self.__appendValue(value) 165 return self.__getAverage()
166