def reflect(self, line): from diofant import atan, Point, Dummy, oo g = self l = line o = Point(0, 0) if l.slope == 0: y = l.args[0].y if not y: # x-axis return g.scale(y=-1) reps = [(p, p.translate(y=2 * (y - p.y))) for p in g.atoms(Point)] elif l.slope == oo: x = l.args[0].x if not x: # y-axis return g.scale(x=-1) reps = [(p, p.translate(x=2 * (x - p.x))) for p in g.atoms(Point)] else: if not hasattr(g, 'reflect') and not all( isinstance(arg, Point) for arg in g.args): raise NotImplementedError( 'reflect undefined or non-Point args in %s' % g) a = atan(l.slope) c = l.coefficients d = -c[-1] / c[1] # y-intercept # apply the transform to a single point x, y = Dummy(), Dummy() xf = Point(x, y) xf = xf.translate(y=-d).rotate(-a, o).scale(y=-1).rotate( a, o).translate(y=d) # replace every point using that transform reps = [(p, xf.xreplace({x: p.x, y: p.y})) for p in g.atoms(Point)] return g.xreplace(dict(reps))
def _eval_subs(self, old, new): from diofant.geometry.point import Point, Point3D if is_sequence(old) or is_sequence(new): if isinstance(self, Point3D): old = Point3D(old) new = Point3D(new) else: old = Point(old) new = Point(new) return self._subs(old, new)
def arbitrary_point(self, parameter='t'): """ A parameterized point on the curve. Parameters ========== parameter : str or Symbol, optional Default value is 't'; the Curve's parameter is selected with None or self.parameter otherwise the provided symbol is used. Returns ======= arbitrary_point : Point Raises ====== ValueError When `parameter` already appears in the functions. See Also ======== diofant.geometry.point.Point Examples ======== >>> from diofant import Symbol >>> from diofant.abc import s >>> from diofant.geometry import Curve >>> C = Curve([2*s, s**2], (s, 0, 2)) >>> C.arbitrary_point() Point2D(2*t, t**2) >>> C.arbitrary_point(C.parameter) Point2D(2*s, s**2) >>> C.arbitrary_point(None) Point2D(2*s, s**2) >>> C.arbitrary_point(Symbol('a')) Point2D(2*a, a**2) """ if parameter is None: return Point(*self.functions) tnew = _symbol(parameter, self.parameter) t = self.parameter if (tnew.name != t.name and tnew.name in (f.name for f in self.free_symbols)): raise ValueError('Symbol %s already appears in object ' 'and cannot be used as a parameter.' % tnew.name) return Point(*[w.subs(t, tnew) for w in self.functions])
def test_geometry(): p1 = Point(1, 2) p2 = Point(2, 3) p3 = Point(0, 0) p4 = Point(0, 1) for c in (GeometryEntity, GeometryEntity(), Point, p1, Circle, Circle(p1, 2), Ellipse, Ellipse(p1, 3, 4), Line, Line(p1, p2), LinearEntity, LinearEntity(p1, p2), Ray, Ray(p1, p2), Segment, Segment(p1, p2), Polygon, Polygon(p1, p2, p3, p4), RegularPolygon, RegularPolygon(p1, 4, 5), Triangle, Triangle(p1, p2, p3)): check(c, check_attr=False)
def test_sympyissue_7457(): pickle.loads(pickle.dumps(Point(1.1, 2.1).evalf())) # not raises a = Float('1.2') b = pickle.loads(pickle.dumps(a)) b.evalf(strict=False) # not raises assert a == b
def rotate(self, angle=0, pt=None): """Rotate ``angle`` radians counterclockwise about Point ``pt``. The default pt is the origin, Point(0, 0). Examples ======== >>> from diofant.geometry.curve import Curve >>> from diofant.abc import x >>> from diofant import pi >>> Curve((x, x), (x, 0, 1)).rotate(pi/2) Curve((-x, x), (x, 0, 1)) """ from diofant.matrices import Matrix, rot_axis3 pt = -Point(pt or (0, 0)) rv = self.translate(*pt.args) f = list(rv.functions) f.append(0) f = Matrix(1, 3, f) f *= rot_axis3(angle) rv = self.func(f[0, :2].tolist()[0], self.limits) if pt is not None: pt = -pt return rv.translate(*pt.args) return rv
def scale(self, x=1, y=1, pt=None): """Scale the object by multiplying the x,y-coordinates by x and y. If pt is given, the scaling is done relative to that point; the object is shifted by -pt, scaled, and shifted by pt. See Also ======== rotate, translate Examples ======== >>> from diofant import RegularPolygon, Point, Polygon >>> t = Polygon(*RegularPolygon(Point(0, 0), 1, 3).vertices) >>> t Triangle(Point2D(1, 0), Point2D(-1/2, sqrt(3)/2), Point2D(-1/2, -sqrt(3)/2)) >>> t.scale(2) Triangle(Point2D(2, 0), Point2D(-1, sqrt(3)/2), Point2D(-1, -sqrt(3)/2)) >>> t.scale(2,2) Triangle(Point2D(2, 0), Point2D(-1, sqrt(3)), Point2D(-1, -sqrt(3))) """ from diofant.geometry.point import Point if pt: pt = Point(pt) return self.translate(*(-pt).args).scale(x, y).translate(*pt.args) return type(self)(*[a.scale(x, y) for a in self.args ]) # if this fails, override this class
def scale(x, y, pt=None): """Return the matrix to multiply a 2-D point's coordinates by x and y. If pt is given, the scaling is done relative to that point.""" rv = eye(3) rv[0, 0] = x rv[1, 1] = y if pt: from diofant.geometry.point import Point pt = Point(pt) tr1 = translate(*(-pt).args) tr2 = translate(*pt.args) return tr1 * rv * tr2 return rv
def scale(self, x=1, y=1, pt=None): """Override GeometryEntity.scale since Curve is not made up of Points. Examples ======== >>> from diofant.geometry.curve import Curve >>> from diofant import pi >>> from diofant.abc import x >>> Curve((x, x), (x, 0, 1)).scale(2) Curve((2*x, x), (x, 0, 1)) """ if pt: pt = Point(pt) return self.translate(*(-pt).args).scale(x, y).translate(*pt.args) fx, fy = self.functions return self.func((fx*x, fy*y), self.limits)
def _eval_subs(self, old, new): if old == self.parameter: return Point(*[f.subs(old, new) for f in self.functions])