Even with integers, you still get complex expressions with square roots as the solutions.
Aaron Meurer On Feb 6, 2013, at 12:54 AM, Ahmed Kachkach <ahmed.kachk...@gmail.com> wrote: I'd need to derive a formula that takes into account all the shapes that are on my map and returns the closest distance (if any). Not sure I can do this. Actually, floating points coordinates are not a requirement in my program, I guess I could just use integers. I just tried converting all the coordinates to integers and it seems like It's still as slow as before. (collision points are rational) ; Maybe because of internal conversions to rationals ? * ------ **Ahmed Kachkach** **Web & graphic designer - Kachkach.com Élève ingénieur à l'INSA de Lyon - 3ème année - Département informatique * *Engineering student at INSA de Lyon - 3rd year - Computer science department* 2013/2/6 Aaron Meurer <asmeu...@gmail.com> > I also didn't try very hard, but it may be difficult to do this. To > make geometry return a symbolic result, it has to be completely > convinced that a Point is contained in another geometry object. I > tried intersecting an arbitrary ellipse with and arbitrary ray, and I > got: > > Undecidable: Cannot determine if Point(x + (x - z)*(sqrt(-((e**2*(x - > z)**2 + hr**2*(t - y)**2)*(-e**2*hr**2 + e**2*(x - x1)**2 + hr**2*(y - > y1)**2) - (e**2*(x - x1)*(x - z) - hr**2*(t - y)*(y - > y1))**2)/(e**4*hr**4)) - (x - x1)*(x - z)/hr**2 + (t - y)*(y - > y1)/e**2)/((x - z)**2/hr**2 + (t - y)**2/e**2), y - (t - > y)*(sqrt(-((e**2*(x - z)**2 + hr**2*(t - y)**2)*(-e**2*hr**2 + e**2*(x > - x1)**2 + hr**2*(y - y1)**2) - (e**2*(x - x1)*(x - z) - hr**2*(t - > y)*(y - y1))**2)/(e**4*hr**4)) - (x - x1)*(x - z)/hr**2 + (t - y)*(y - > y1)/e**2)/((x - z)**2/hr**2 + (t - y)**2/e**2)) is in Ray(Point(x, y), > Point(z, t)) > > which is not too surprising, since as you note, not all rays intersect > all ellipses. But it might be hard to convince the geometry module > using the assumptions that they do. Or it may work. It depends on what > conditions you know ahead of time. > > It would be nice if instead of raising Undecidable, it created some > kind of symbolic Intersection object, which then becomes evaluated if > symbols are replaced with numbers, and also knows how to numerically > compute itself efficiently given floating point values (so that it > would be useable with something like lambdify). > > Aaron Meurer > > On Tue, Feb 5, 2013 at 6:02 PM, Ronan Lamy <ronan.l...@gmail.com> wrote: > > Le 05/02/2013 19:54, Ahmed Kachkach a écrit : > > > >> Hi ! > >> > >> For a robotics simulation, I need to calculate the distance that an > >> ultrasound sensor would measure (=> distance to the closest obstacle). > >> > >> Here's the code I'm using to do so (knowing that what's in "self.shapes" > >> has been parsed from an SVG file and is mainly ellipses): > >> > >> def RayDistance(self, x, y, headingAngle): > >> > >> ray = Ray(Point(x,y), angle=headingAngle) > >> > >> minDist = None > >> > >> for shape in self.shapes: > >> > >> intersections = ray.intersection(shape) > >> > >> for intersection in intersections: > >> > >> distance = intersection.distance(ray.source) > >> > >> print "Shape {} ; Intersection {} ; Distance {}".format(shape, > >> intersection, distance) > >> > >> if minDist == None: > >> > >> minDist = distance > >> > >> elif distance < minDist: > >> > >> minDist = distance > >> > >> return minDist > >> > >> > >> Doing this is extremely slow, even with just 3 shapes. If I go up to 200 > >> shapes, I only get about 1 frame per second. And I only detectect a > >> collision from time to time (especially if I slightly change my heading > >> angle while facing a same obstacle). > >> > >> For instance, I'm using Qt for the visualisation and my "headingAngle" > >> is in radians and ccw (0 being horizantal, headed to the positive x), my > >> coordinates are floats and using the graphical reference system (=> > >> positive Xs to the "right" and positive Ys to the bottom) > >> > >> It's my first experience with Sympy, so I may just be using the wrong > >> tools for what I'm trying to do. > > > > > > Well, whenever you try to call sympy functions with floating point > arguments > > repeatedly, you are doing it wrong. In this case, you should not call > sympy > > functions at runtime. Instead, you should use symbolic computations to > > derive the relevant formulas, convert them to numpy functions, and use > only > > numpy at runtime. Schematically, it would look like: > > > > import sympy as sy > > import numpy as np > > > > x, y, angle, a, b, c = sy.symbols("x, y, theta, a, b, c", real=True) > > > > def make_ellipse(param_a, param_b, param_c): > > """Convert ellipse params to Ellipse object""" > > ... > > > > # Derive the formula > > ray = sy.Ray(sy.Point(x, y), angle=angle) > > ellipse = make_ellipse(a, b, c) > > intersection = ray.intersection(ellipse) > > closest_point = intersection[0] # a bit of wishful thinking here... > > distance = closest_point.distance(ray.source) > > > > # Make a numerical function > > n_distance = sy.lambdify([x, y, angle, a, b, c], distance, "numpy") > > > > # assuming self.params is a n-by-3 numpy array of ellipse parameters > > def ray_distance(self, x, y, angle): > > return np.min(n_distance(x, y, angle, self.params[:, 0], > > self.params[:, 1], self.params[:, 2])) > > > > Now, I haven't tested this, and I have completely ignored the fact that > not > > all ellipses intersect the ray, but I hope that you get the idea. If you > can > > put your calculations in this form, it should be orders magnitudes faster > > than your first attempt. > > > > Ronan > > > > > > > > -- > > You received this message because you are subscribed to the Google Groups > > "sympy" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to sympy+unsubscr...@googlegroups.com. > > To post to this group, send email to sympy@googlegroups.com. > > Visit this group at http://groups.google.com/group/sympy?hl=en. > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sympy+unsubscr...@googlegroups.com. > To post to this group, send email to sympy@googlegroups.com. > Visit this group at http://groups.google.com/group/sympy?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. Visit this group at http://groups.google.com/group/sympy?hl=en. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. Visit this group at http://groups.google.com/group/sympy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.