def intersection(self, o): if isinstance(o, Circle): dx,dy = o._c - self.center d = Basic.sqrt( simplify(dy**2 + dx**2) ) a = simplify((self.radius**2 - o.radius**2 + d**2) / (2*d)) x2 = self.center[0] + (dx * a/d) y2 = self.center[1] + (dy * a/d) h = Basic.sqrt( simplify(self.radius**2 - a**2) ) rx = -dy * (h/d) ry = dx * (h/d) xi_1 = simplify(x2 + rx) xi_2 = simplify(x2 - rx) yi_1 = simplify(y2 + ry) yi_2 = simplify(y2 - ry) ret = [Point(xi_1, yi_1)] if xi_1 != xi_2 or yi_1 != yi_2: ret.append(Point(xi_2, yi_2)) return ret elif isinstance(o, Ellipse): a, b, r = o.hradius, o.vradius, self.radius x = a*Basic.sqrt(simplify((r**2 - b**2)/(a**2 - b**2))) y = b*Basic.sqrt(simplify((a**2 - r**2)/(a**2 - b**2))) return list(set([Point(x,y), Point(x,-y), Point(-x,y), Point(-x,-y)])) return Ellipse.intersection(self, o)
def _eval_apply(self, arg): arg = Basic.sympify(arg) if isinstance(arg, Basic.Number): if isinstance(arg, Basic.NaN): return S.NaN #elif isinstance(arg, Basic.Zero): # return S.ComplexInfinity elif arg.is_negative: return -self(-arg) else: i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return -S.ImaginaryUnit * Basic.coth(i_coeff) else: pi_coeff = arg.as_coefficient(S.Pi) if pi_coeff is not None: #if pi_coeff.is_integer: # return S.ComplexInfinity if isinstance(pi_coeff, Basic.Rational): cst_table = { 2 : S.Zero, 3 : 1 / Basic.sqrt(3), 4 : S.One, 6 : Basic.sqrt(3) } try: result = cst_table[pi_coeff.q] if (2*pi_coeff.p // pi_coeff.q) % 4 in (1, 3): return -result else: return result except KeyError: pass coeff, terms = arg.as_coeff_terms() if coeff.is_negative: return -self(-arg)
def _eval_apply(self, arg): arg = Basic.sympify(arg) if isinstance(arg, Basic.Number): if isinstance(arg, Basic.NaN): return S.NaN elif isinstance(arg, Basic.Zero): return S.Zero elif arg.is_negative: return -self(-arg) else: i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return S.ImaginaryUnit * Basic.sinh(i_coeff) else: pi_coeff = arg.as_coefficient(S.Pi) if pi_coeff is not None: if pi_coeff.is_integer: return S.Zero elif isinstance(pi_coeff, Basic.Rational): cst_table = { 2 : S.One, 3 : S.Half*Basic.sqrt(3), 4 : S.Half*Basic.sqrt(2), 6 : S.Half, } try: result = cst_table[pi_coeff.q] if (pi_coeff.p // pi_coeff.q) % 2 == 1: return -result else: return result except KeyError: pass coeff, terms = arg.as_coeff_terms() if coeff.is_negative: return -self(-arg)
def _eval_apply(self, arg): if isinstance(arg, Basic.NaN): return S.NaN if arg.is_positive: return arg if arg.is_negative: return -arg coeff, terms = arg.as_coeff_terms() if not isinstance(coeff, Basic.One): return self(coeff) * self(Basic.Mul(*terms)) if arg.is_real is False: return Basic.sqrt( (arg * arg.conjugate()).expand() ) return
def distance(p1, p2): """ Get the Euclidean distance between two points. Example: ======== >>> p1,p2 = Point(1, 1), Point(4, 5) >>> Point.distance(p1, p2) 5 """ return Basic.sqrt( sum([(a-b)**2 for a,b in zip(p1,p2)]) )
def taylor_term(self, n, x, *previous_terms): if n < 0 or n % 2 == 0: return S.Zero else: x = Basic.sympify(x) k = (n - 1)/2 if len(previous_terms) > 2: return -previous_terms[-2] * x**2 * (n-2)/(n*k) else: return 2*(-1)**k * x**n/(n*Basic.Factorial(k)*Basic.sqrt(S.Pi))
def _eval_apply(self, arg): arg = Basic.sympify(arg) if isinstance(arg, Basic.Number): if isinstance(arg, Basic.NaN): return S.NaN elif isinstance(arg, Basic.Infinity): return S.Infinity * S.ImaginaryUnit elif isinstance(arg, Basic.NegativeInfinity): return S.NegativeInfinity * S.ImaginaryUnit elif isinstance(arg, Basic.Zero): return S.Pi / 2 elif isinstance(arg, Basic.One): return S.Zero elif isinstance(arg, Basic.NegativeOne): return S.Pi else: cst_table = { S.Half : S.Pi/3, -S.Half : 2*S.Pi/3, Basic.sqrt(2)/2 : S.Pi/4, -Basic.sqrt(2)/2 : 3*S.Pi/4, 1/Basic.sqrt(2) : S.Pi/4, -1/Basic.sqrt(2) : 3*S.Pi/4, Basic.sqrt(3)/2 : S.Pi/6, -Basic.sqrt(3)/2 : 5*S.Pi/6, } if arg in cst_table: return cst_table[arg]
def foci(self): """The foci of the ellipse, if the radii are numerical.""" c = self.center if self.hradius == self.vradius: return c hr, vr = self.hradius, self.vradius if hr.atoms(type=Basic.Symbol) or vr.atoms(type=Basic.Symbol): raise Exception("foci can only be determined on non-symbolic radii") v = Basic.sqrt(abs(vr**2 - hr**2)) if hr < vr: return (c+Point(0, -v), c+Point(0, v)) else: return (c+Point(-v, 0), c+Point(v, 0))
def _do_line_intersection(self, o): """ Find the intersection of a LinearEntity and the ellipse. Makes no regards to what the LinearEntity is because it assumes a Line. To ensure correct intersection results one must invoke intersection() to remove bad results. """ def dot(p1, p2): sum = 0 for ind in xrange(0, len(p1)): sum += p1[ind] * p2[ind] return simplify(sum) hr_sq = self.hradius ** 2 vr_sq = self.vradius ** 2 lp = o.points ldir = lp[1] - lp[0] diff = lp[0] - self.center mdir = (ldir[0] / hr_sq, ldir[1] / vr_sq) mdiff = (diff[0] / hr_sq, diff[1] / vr_sq) a = dot(ldir, mdir) b = dot(ldir, mdiff) c = dot(diff, mdiff) - 1 det = simplify(b*b - a*c); result = [] if det == 0: t = -b / a result.append( lp[0] + (lp[1] - lp[0]) * t ) else: is_good = True try: is_good = (det > 0) except NotImplementedError: #symbolic, allow is_good = True if is_good: root = Basic.sqrt(det) t_a = (-b - root) / a t_b = (-b + root) / a result.append( lp[0] + (lp[1] - lp[0]) * t_a ) result.append( lp[0] + (lp[1] - lp[0]) * t_b ) return result
def _eval_apply(self, arg): arg = Basic.sympify(arg) if isinstance(arg, Basic.Number): if isinstance(arg, Basic.NaN): return S.NaN elif isinstance(arg, Basic.Infinity): return S.NegativeInfinity * S.ImaginaryUnit elif isinstance(arg, Basic.NegativeInfinity): return S.Infinity * S.ImaginaryUnit elif isinstance(arg, Basic.Zero): return S.Zero elif isinstance(arg, Basic.One): return S.Pi / 2 elif isinstance(arg, Basic.NegativeOne): return -S.Pi / 2 else: cst_table = { S.Half : 6, -S.Half : -6, Basic.sqrt(2)/2 : 4, -Basic.sqrt(2)/2 : -4, 1/Basic.sqrt(2) : 4, -1/Basic.sqrt(2) : -4, Basic.sqrt(3)/2 : 3, -Basic.sqrt(3)/2 : -3, } if arg in cst_table: return S.Pi / cst_table[arg] elif arg.is_negative: return -self(-arg) else: i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return S.ImaginaryUnit * Basic.asinh(i_coeff) else: coeff, terms = arg.as_coeff_terms() if coeff.is_negative: return -self(-arg)
def _eval_apply(cls, arg): arg = Basic.sympify(arg) if isinstance(arg, Basic.Number): if isinstance(arg, Basic.NaN): return S.NaN elif isinstance(arg, Basic.Infinity): return S.Zero elif isinstance(arg, Basic.NegativeInfinity): return S.Zero elif isinstance(arg, Basic.Zero): return S.Pi/ 2 elif isinstance(arg, Basic.One): return S.Pi / 4 elif isinstance(arg, Basic.NegativeOne): return -S.Pi / 4 else: cst_table = { Basic.sqrt(3)/3 : 3, -Basic.sqrt(3)/3 : -3, 1/Basic.sqrt(3) : 3, -1/Basic.sqrt(3) : -3, Basic.sqrt(3) : 6, -Basic.sqrt(3) : -6, } if arg in cst_table: return S.Pi / cst_table[arg] elif arg.is_negative: return -cls(-arg) else: i_coeff = arg.as_coefficient(S.ImaginaryUnit) if i_coeff is not None: return -S.ImaginaryUnit * Basic.acoth(i_coeff) else: coeff, terms = arg.as_coeff_terms() if coeff.is_negative: return -cls(-arg)
def fdiff(self, argindex=1): if argindex == 1: return 2*Basic.exp(-self[0]**2)/Basic.sqrt(S.Pi) else: raise ArgumentIndexError(self, argindex)