def test_Geometry(): sT(Point(0, 0), "Point2D(Integer(0), Integer(0))") sT(Ellipse(Point(0, 0), 5, 1), "Ellipse(Point2D(Integer(0), Integer(0)), Integer(5), Integer(1))")
def test_issue_12966(): poly = Polygon(Point(0, 0), Point(0, 10), Point(5, 10), Point(5, 5), Point(10, 5), Point(10, 0)) t = Symbol('t') pt = poly.arbitrary_point(t) DELTA = 5/poly.perimeter assert [pt.subs(t, DELTA*i) for i in range(int(1/DELTA))] == [ Point(0, 0), Point(0, 5), Point(0, 10), Point(5, 10), Point(5, 5), Point(10, 5), Point(10, 0), Point(5, 0)]
def convex_hull(*args, **kwargs): """The convex hull surrounding the Points contained in the list of entities. Parameters ========== args : a collection of Points, Segments and/or Polygons Returns ======= convex_hull : Polygon if ``polygon`` is True else as a tuple `(U, L)` where ``L`` and ``U`` are the lower and upper hulls, respectively. Notes ===== This can only be performed on a set of points whose coordinates can be ordered on the number line. References ========== [1] http://en.wikipedia.org/wiki/Graham_scan [2] Andrew's Monotone Chain Algorithm (A.M. Andrew, "Another Efficient Algorithm for Convex Hulls in Two Dimensions", 1979) http://geomalgorithms.com/a10-_hull-1.html See Also ======== sympy.geometry.point.Point, sympy.geometry.polygon.Polygon Examples ======== >>> from sympy.geometry import Point, convex_hull >>> points = [(1, 1), (1, 2), (3, 1), (-5, 2), (15, 4)] >>> convex_hull(*points) Polygon(Point2D(-5, 2), Point2D(1, 1), Point2D(3, 1), Point2D(15, 4)) >>> convex_hull(*points, **dict(polygon=False)) ([Point2D(-5, 2), Point2D(15, 4)], [Point2D(-5, 2), Point2D(1, 1), Point2D(3, 1), Point2D(15, 4)]) """ from .entity import GeometryEntity from .point import Point from .line import Segment from .polygon import Polygon polygon = kwargs.get('polygon', True) p = set() for e in args: if not isinstance(e, GeometryEntity): try: e = Point(e) except NotImplementedError: raise ValueError( '%s is not a GeometryEntity and cannot be made into Point' % str(e)) if isinstance(e, Point): p.add(e) elif isinstance(e, Segment): p.update(e.points) elif isinstance(e, Polygon): p.update(e.vertices) else: raise NotImplementedError('Convex hull for %s not implemented.' % type(e)) # make sure all our points are of the same dimension if any(len(x) != 2 for x in p): raise ValueError('Can only compute the convex hull in two dimensions') p = list(p) if len(p) == 1: return p[0] if polygon else (p[0], None) elif len(p) == 2: s = Segment(p[0], p[1]) return s if polygon else (s, None) def _orientation(p, q, r): '''Return positive if p-q-r are clockwise, neg if ccw, zero if collinear.''' return (q.y - p.y) * (r.x - p.x) - (q.x - p.x) * (r.y - p.y) # scan to find upper and lower convex hulls of a set of 2d points. U = [] L = [] try: p.sort(key=lambda x: x.args) except TypeError: raise ValueError("The points could not be sorted.") for p_i in p: while len(U) > 1 and _orientation(U[-2], U[-1], p_i) <= 0: U.pop() while len(L) > 1 and _orientation(L[-2], L[-1], p_i) >= 0: L.pop() U.append(p_i) L.append(p_i) U.reverse() convexHull = tuple(L + U[1:-1]) if len(convexHull) == 2: s = Segment(convexHull[0], convexHull[1]) return s if polygon else (s, None) if polygon: return Polygon(*convexHull) else: U.reverse() return (U, L)
def test_medians(): t = Triangle(Point(0, 0), Point(1, 0), Point(0, 1)) assert t.medians[Point(0, 0)] == Segment(Point(0, 0), Point(S(1)/2, S(1)/2))
def test_nine_point_circle(): assert Triangle(Point(0, 0), Point(1, 0), Point(0, 1)).nine_point_circle \ == Circle(Point2D(S(1)/4, S(1)/4), sqrt(2)/4)
def test_incenter(): assert Triangle(Point(0, 0), Point(1, 0), Point(0, 1)).incenter \ == Point(1 - sqrt(2)/2, 1 - sqrt(2)/2)
def test_incircle(): assert Triangle(Point(0, 0), Point(2, 0), Point(0, 2)).incircle \ == Circle(Point(2 - sqrt(2), 2 - sqrt(2)), 2 - sqrt(2))
def test_issue_15259(): assert Circle((1, 2), 0) == Point(1, 2)
def test_geometry(): p = sympify(Point(0, 1)) assert p == Point(0, 1) and isinstance(p, Point) L = sympify(Line(p, (1, 0))) assert L == Line((0, 1), (1, 0)) and isinstance(L, Line)
def test_nine_point_circle(): assert Triangle(Point(0, 0), Point(1, 0), Point(0, 1)).nine_point_circle \ == Circle(Point2D(Rational(1, 4), Rational(1, 4)), sqrt(2)/4)
def test_intersection(): poly1 = Triangle(Point(0, 0), Point(1, 0), Point(0, 1)) poly2 = Polygon(Point(0, 1), Point(-5, 0), Point(0, -4), Point(0, Rational(1, 5)), Point(S.Half, -0.1), Point(1, 0), Point(0, 1)) assert poly1.intersection(poly2) == [ Point2D(Rational(1, 3), 0), Segment(Point(0, Rational(1, 5)), Point(0, 0)), Segment(Point(1, 0), Point(0, 1)) ] assert poly2.intersection(poly1) == [ Point(Rational(1, 3), 0), Segment(Point(0, 0), Point(0, Rational(1, 5))), Segment(Point(1, 0), Point(0, 1)) ] assert poly1.intersection(Point(0, 0)) == [Point(0, 0)] assert poly1.intersection(Point(-12, -43)) == [] assert poly2.intersection(Line((-12, 0), (12, 0))) == [ Point(-5, 0), Point(0, 0), Point(Rational(1, 3), 0), Point(1, 0) ] assert poly2.intersection(Line((-12, 12), (12, 12))) == [] assert poly2.intersection(Ray( (-3, 4), (1, 0))) == [Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(Circle((0, -1), 1)) == [Point(0, -2), Point(0, 0)] assert poly1.intersection(poly1) == [ Segment(Point(0, 0), Point(1, 0)), Segment(Point(0, 1), Point(0, 0)), Segment(Point(1, 0), Point(0, 1)) ] assert poly2.intersection(poly2) == [ Segment(Point(-5, 0), Point(0, -4)), Segment(Point(0, -4), Point(0, Rational(1, 5))), Segment(Point(0, Rational(1, 5)), Point(S.Half, Rational(-1, 10))), Segment(Point(0, 1), Point(-5, 0)), Segment(Point(S.Half, Rational(-1, 10)), Point(1, 0)), Segment(Point(1, 0), Point(0, 1)) ] assert poly2.intersection(Triangle(Point(0, 1), Point(1, 0), Point(-1, 1))) \ == [Point(Rational(-5, 7), Rational(6, 7)), Segment(Point2D(0, 1), Point(1, 0))] assert poly1.intersection(RegularPolygon((-12, -15), 3, 3)) == []
def test_medial(): assert Triangle(Point(0, 0), Point(1, 0), Point(0, 1)).medial \ == Triangle(Point(S.Half, 0), Point(S.Half, S.Half), Point(0, S.Half))
def test_medians(): t = Triangle(Point(0, 0), Point(1, 0), Point(0, 1)) assert t.medians[Point(0, 0)] == Segment(Point(0, 0), Point(S.Half, S.Half))
def test_transform(): pts = [Point(0, 0), Point(S.Half, Rational(1, 4)), Point(1, 1)] pts_out = [Point(-4, -10), Point(-3, Rational(-37, 4)), Point(-2, -7)] assert Triangle(*pts).scale(2, 3, (4, 5)) == Triangle(*pts_out) assert RegularPolygon((0, 0), 1, 4).scale(2, 3, (4, 5)) == \ Polygon(Point(-2, -10), Point(-4, -7), Point(-6, -10), Point(-4, -13))
def test_reflect(): x = Symbol('x', real=True) y = Symbol('y', real=True) b = Symbol('b') m = Symbol('m') l = Line((0, b), slope=m) p = Point(x, y) r = p.reflect(l) dp = l.perpendicular_segment(p).length dr = l.perpendicular_segment(r).length assert verify_numerically(dp, dr) t = Triangle((0, 0), (1, 0), (2, 3)) assert Polygon((1, 0), (2, 0), (2, 2)).reflect(Line((3, 0), slope=oo)) \ == Triangle(Point(5, 0), Point(4, 0), Point(4, 2)) assert Polygon((1, 0), (2, 0), (2, 2)).reflect(Line((0, 3), slope=oo)) \ == Triangle(Point(-1, 0), Point(-2, 0), Point(-2, 2)) assert Polygon((1, 0), (2, 0), (2, 2)).reflect(Line((0, 3), slope=0)) \ == Triangle(Point(1, 6), Point(2, 6), Point(2, 4)) assert Polygon((1, 0), (2, 0), (2, 2)).reflect(Line((3, 0), slope=0)) \ == Triangle(Point(1, 0), Point(2, 0), Point(2, -2))
def test_subs(): x = Symbol("x", real=True) y = Symbol("y", real=True) p = Point(x, 2) q = Point(1, 1) r = Point(3, 4) for o in [ p, Segment(p, q), Ray(p, q), Line(p, q), Triangle(p, q, r), RegularPolygon(p, 3, 6), Polygon(p, q, r, Point(5, 4)), Circle(p, 3), Ellipse(p, 3, 4), ]: assert "y" in str(o.subs(x, y)) assert p.subs({x: 1}) == Point(1, 2) assert Point(1, 2).subs(Point(1, 2), Point(3, 4)) == Point(3, 4) assert Point(1, 2).subs((1, 2), Point(3, 4)) == Point(3, 4) assert Point(1, 2).subs(Point(1, 2), Point(3, 4)) == Point(3, 4) assert Point(1, 2).subs({(1, 2)}) == Point(2, 2) raises(ValueError, lambda: Point(1, 2).subs(1)) raises(ValueError, lambda: Point(1, 1).subs( (Point(1, 1), Point(1, 2)), 1, 2))
def test_bisectors(): p1, p2, p3 = Point(0, 0), Point(1, 0), Point(0, 1) t = Triangle(p1, p2, p3) assert t.bisectors()[p2] == Segment(Point(1, 0), Point(0, sqrt(2) - 1))
def test_Geometry(): assert sstr(Point(0, 0)) == 'Point(0, 0)' assert sstr(Circle(Point(0, 0), 3)) == 'Circle(Point(0, 0), 3)'
def test_inradius(): assert Triangle(Point(0, 0), Point(4, 0), Point(0, 3)).inradius == 1
def test_ellipse_geom(): x = Symbol('x', real=True) y = Symbol('y', real=True) t = Symbol('t', real=True) y1 = Symbol('y1', real=True) half = Rational(1, 2) p1 = Point(0, 0) p2 = Point(1, 1) p4 = Point(0, 1) e1 = Ellipse(p1, 1, 1) e2 = Ellipse(p2, half, 1) e3 = Ellipse(p1, y1, y1) c1 = Circle(p1, 1) c2 = Circle(p2, 1) c3 = Circle(Point(sqrt(2), sqrt(2)), 1) l1 = Line(p1, p2) # Test creation with three points cen, rad = Point(3*half, 2), 5*half assert Circle(Point(0, 0), Point(3, 0), Point(0, 4)) == Circle(cen, rad) raises( GeometryError, lambda: Circle(Point(0, 0), Point(1, 1), Point(2, 2))) raises(ValueError, lambda: Ellipse(None, None, None, 1)) raises(GeometryError, lambda: Circle(Point(0, 0))) # Basic Stuff assert Ellipse(None, 1, 1).center == Point(0, 0) assert e1 == c1 assert e1 != e2 assert e1 != l1 assert p4 in e1 assert p2 not in e2 assert e1.area == pi assert e2.area == pi/2 assert e3.area == pi*y1*abs(y1) assert c1.area == e1.area assert c1.circumference == e1.circumference assert e3.circumference == 2*pi*y1 assert e1.plot_interval() == e2.plot_interval() == [t, -pi, pi] assert e1.plot_interval(x) == e2.plot_interval(x) == [x, -pi, pi] assert Ellipse(None, 1, None, 1).circumference == 2*pi assert c1.minor == 1 assert c1.major == 1 assert c1.hradius == 1 assert c1.vradius == 1 # Private Functions assert hash(c1) == hash(Circle(Point(1, 0), Point(0, 1), Point(0, -1))) assert c1 in e1 assert (Line(p1, p2) in e1) is False assert e1.__cmp__(e1) == 0 assert e1.__cmp__(Point(0, 0)) > 0 # Encloses assert e1.encloses(Segment(Point(-0.5, -0.5), Point(0.5, 0.5))) is True assert e1.encloses(Line(p1, p2)) is False assert e1.encloses(Ray(p1, p2)) is False assert e1.encloses(e1) is False assert e1.encloses( Polygon(Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5))) is True assert e1.encloses(RegularPolygon(p1, 0.5, 3)) is True assert e1.encloses(RegularPolygon(p1, 5, 3)) is False assert e1.encloses(RegularPolygon(p2, 5, 3)) is False # with generic symbols, the hradius is assumed to contain the major radius M = Symbol('M') m = Symbol('m') c = Ellipse(p1, M, m).circumference _x = c.atoms(Dummy).pop() assert c == 4*M*Integral( sqrt((1 - _x**2*(M**2 - m**2)/M**2)/(1 - _x**2)), (_x, 0, 1)) assert e2.arbitrary_point() in e2 # Foci f1, f2 = Point(sqrt(12), 0), Point(-sqrt(12), 0) ef = Ellipse(Point(0, 0), 4, 2) assert ef.foci in [(f1, f2), (f2, f1)] # Tangents v = sqrt(2) / 2 p1_1 = Point(v, v) p1_2 = p2 + Point(half, 0) p1_3 = p2 + Point(0, 1) assert e1.tangent_lines(p4) == c1.tangent_lines(p4) assert e2.tangent_lines(p1_2) == [Line(Point(3/2, 1), Point(3/2, 1/2))] assert e2.tangent_lines(p1_3) == [Line(Point(1, 2), Point(5/4, 2))] assert c1.tangent_lines(p1_1) != [Line(p1_1, Point(0, sqrt(2)))] assert c1.tangent_lines(p1) == [] assert e2.is_tangent(Line(p1_2, p2 + Point(half, 1))) assert e2.is_tangent(Line(p1_3, p2 + Point(half, 1))) assert c1.is_tangent(Line(p1_1, Point(0, sqrt(2)))) assert e1.is_tangent(Line(Point(0, 0), Point(1, 1))) is False assert c1.is_tangent(e1) is True assert c1.is_tangent(Ellipse(Point(2, 0), 1, 1)) is True assert c1.is_tangent( Polygon(Point(1, 1), Point(1, -1), Point(2, 0))) is True assert c1.is_tangent( Polygon(Point(1, 1), Point(1, 0), Point(2, 0))) is False assert Circle(Point(5, 5), 3).is_tangent(Circle(Point(0, 5), 1)) is False assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(77/25, 132/25)), Line(Point(0, 0), Point(33/5, 22/5))] assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(3, 4)) == \ [Line(Point(3, 4), Point(4, 4)), Line(Point(3, 4), Point(3, 5))] assert Circle(Point(5, 5), 2).tangent_lines(Point(3, 3)) == \ [Line(Point(3, 3), Point(4, 3)), Line(Point(3, 3), Point(3, 4))] assert Circle(Point(5, 5), 2).tangent_lines(Point(5 - 2*sqrt(2), 5)) == \ [Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 - sqrt(2))), Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 + sqrt(2))), ] # for numerical calculations, we shouldn't demand exact equality, # so only test up to the desired precision def lines_close(l1, l2, prec): """ tests whether l1 and 12 are within 10**(-prec) of each other """ return abs(l1.p1 - l2.p1) < 10**(-prec) and abs(l1.p2 - l2.p2) < 10**(-prec) def line_list_close(ll1, ll2, prec): return all(lines_close(l1, l2, prec) for l1, l2 in zip(ll1, ll2)) e = Ellipse(Point(0, 0), 2, 1) assert e.normal_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(0, 1)), Line(Point(0, 0), Point(1, 0))] assert e.normal_lines(Point(1, 0)) == \ [Line(Point(0, 0), Point(1, 0))] assert e.normal_lines((0, 1)) == \ [Line(Point(0, 0), Point(0, 1))] assert line_list_close(e.normal_lines(Point(1, 1), 2), [ Line(Point(-51/26, -1/5), Point(-25/26, 17/83)), Line(Point(28/29, -7/8), Point(57/29, -9/2))], 2) # test the failure of Poly.intervals and checks a point on the boundary p = Point(sqrt(3), S.Half) assert p in e assert line_list_close(e.normal_lines(p, 2), [ Line(Point(-341/171, -1/13), Point(-170/171, 5/64)), Line(Point(26/15, -1/2), Point(41/15, -43/26))], 2) # be sure to use the slope that isn't undefined on boundary e = Ellipse((0, 0), 2, 2*sqrt(3)/3) assert line_list_close(e.normal_lines((1, 1), 2), [ Line(Point(-64/33, -20/71), Point(-31/33, 2/13)), Line(Point(1, -1), Point(2, -4))], 2) # general ellipse fails except under certain conditions e = Ellipse((0, 0), x, 1) assert e.normal_lines((x + 1, 0)) == [Line(Point(0, 0), Point(1, 0))] raises(NotImplementedError, lambda: e.normal_lines((x + 1, 1))) # Properties major = 3 minor = 1 e4 = Ellipse(p2, minor, major) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major*(1 - ecc) assert e4.apoapsis == major*(1 + ecc) assert e4.semilatus_rectum == major*(1 - ecc ** 2) # independent of orientation e4 = Ellipse(p2, major, minor) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major*(1 - ecc) assert e4.apoapsis == major*(1 + ecc) # Intersection l1 = Line(Point(1, -5), Point(1, 5)) l2 = Line(Point(-5, -1), Point(5, -1)) l3 = Line(Point(-1, -1), Point(1, 1)) l4 = Line(Point(-10, 0), Point(0, 10)) pts_c1_l3 = [Point(sqrt(2)/2, sqrt(2)/2), Point(-sqrt(2)/2, -sqrt(2)/2)] assert intersection(e2, l4) == [] assert intersection(c1, Point(1, 0)) == [Point(1, 0)] assert intersection(c1, l1) == [Point(1, 0)] assert intersection(c1, l2) == [Point(0, -1)] assert intersection(c1, l3) in [pts_c1_l3, [pts_c1_l3[1], pts_c1_l3[0]]] assert intersection(c1, c2) == [Point(0, 1), Point(1, 0)] assert intersection(c1, c3) == [Point(sqrt(2)/2, sqrt(2)/2)] assert e1.intersection(l1) == [Point(1, 0)] assert e2.intersection(l4) == [] assert e1.intersection(Circle(Point(0, 2), 1)) == [Point(0, 1)] assert e1.intersection(Circle(Point(5, 0), 1)) == [] assert e1.intersection(Ellipse(Point(2, 0), 1, 1)) == [Point(1, 0)] assert e1.intersection(Ellipse(Point(5, 0), 1, 1)) == [] assert e1.intersection(Point(2, 0)) == [] assert e1.intersection(e1) == e1 assert intersection(Ellipse(Point(0, 0), 2, 1), Ellipse(Point(3, 0), 1, 2)) == [Point(2, 0)] assert intersection(Circle(Point(0, 0), 2), Circle(Point(3, 0), 1)) == [Point(2, 0)] assert intersection(Circle(Point(0, 0), 2), Circle(Point(7, 0), 1)) == [] assert intersection(Ellipse(Point(0, 0), 5, 17), Ellipse(Point(4, 0), 1, 0.2)) == [Point(5, 0)] assert intersection(Ellipse(Point(0, 0), 5, 17), Ellipse(Point(4, 0), 0.999, 0.2)) == [] assert Circle((0, 0), 1/2).intersection( Triangle((-1, 0), (1, 0), (0, 1))) == [ Point(-1/2, 0), Point(1/2, 0)] raises(TypeError, lambda: intersection(e2, Line((0, 0, 0), (0, 0, 1)))) raises(TypeError, lambda: intersection(e2, Rational(12))) # some special case intersections csmall = Circle(p1, 3) cbig = Circle(p1, 5) cout = Circle(Point(5, 5), 1) # one circle inside of another assert csmall.intersection(cbig) == [] # separate circles assert csmall.intersection(cout) == [] # coincident circles assert csmall.intersection(csmall) == csmall v = sqrt(2) t1 = Triangle(Point(0, v), Point(0, -v), Point(v, 0)) points = intersection(t1, c1) assert len(points) == 4 assert Point(0, 1) in points assert Point(0, -1) in points assert Point(v/2, v/2) in points assert Point(v/2, -v/2) in points circ = Circle(Point(0, 0), 5) elip = Ellipse(Point(0, 0), 5, 20) assert intersection(circ, elip) in \ [[Point(5, 0), Point(-5, 0)], [Point(-5, 0), Point(5, 0)]] assert elip.tangent_lines(Point(0, 0)) == [] elip = Ellipse(Point(0, 0), 3, 2) assert elip.tangent_lines(Point(3, 0)) == \ [Line(Point(3, 0), Point(3, -12))] e1 = Ellipse(Point(0, 0), 5, 10) e2 = Ellipse(Point(2, 1), 4, 8) a = 53/17 c = 2*sqrt(3991)/17 ans = [Point(a - c/8, a/2 + c), Point(a + c/8, a/2 - c)] assert e1.intersection(e2) == ans e2 = Ellipse(Point(x, y), 4, 8) c = sqrt(3991) ans = [Point(-c/68 + a, 2*c/17 + a/2), Point(c/68 + a, -2*c/17 + a/2)] assert [p.subs({x: 2, y:1}) for p in e1.intersection(e2)] == ans # Combinations of above assert e3.is_tangent(e3.tangent_lines(p1 + Point(y1, 0))[0]) e = Ellipse((1, 2), 3, 2) assert e.tangent_lines(Point(10, 0)) == \ [Line(Point(10, 0), Point(1, 0)), Line(Point(10, 0), Point(14/5, 18/5))] # encloses_point e = Ellipse((0, 0), 1, 2) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point( e.center + Point(e.hradius + Rational(1, 10), 0)) is False e = Ellipse((0, 0), 2, 1) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point( e.center + Point(e.hradius + Rational(1, 10), 0)) is False assert c1.encloses_point(Point(1, 0)) is False assert c1.encloses_point(Point(0.3, 0.4)) is True assert e.scale(2, 3) == Ellipse((0, 0), 4, 3) assert e.scale(3, 6) == Ellipse((0, 0), 6, 6) assert e.rotate(pi) == e assert e.rotate(pi, (1, 2)) == Ellipse(Point(2, 4), 2, 1) raises(NotImplementedError, lambda: e.rotate(pi/3)) # Circle rotation tests (Issue #11743) # Link - https://github.com/sympy/sympy/issues/11743 cir = Circle(Point(1, 0), 1) assert cir.rotate(pi/2) == Circle(Point(0, 1), 1) assert cir.rotate(pi/3) == Circle(Point(1/2, sqrt(3)/2), 1) assert cir.rotate(pi/3, Point(1, 0)) == Circle(Point(1, 0), 1) assert cir.rotate(pi/3, Point(0, 1)) == Circle(Point(1/2 + sqrt(3)/2, 1/2 + sqrt(3)/2), 1)
def test_exradii(): t = Triangle(Point(0, 0), Point(6, 0), Point(0, 2)) assert t.exradii[t.sides[2]] == (-2 + sqrt(10))
def test_parameter_value(): t = Symbol('t') e = Ellipse(Point(0, 0), 3, 5) assert e.parameter_value((3, 0), t) == {t: 0} raises(ValueError, lambda: e.parameter_value((4, 0), t))
def test_medial(): assert Triangle(Point(0, 0), Point(1, 0), Point(0, 1)).medial \ == Triangle(Point(S(1)/2, 0), Point(S(1)/2, S(1)/2), Point(0, S(1)/2))
def test_polygon(): x = Symbol('x', real=True) y = Symbol('y', real=True) q = Symbol('q', real=True) u = Symbol('u', real=True) v = Symbol('v', real=True) w = Symbol('w', real=True) x1 = Symbol('x1', real=True) half = Rational(1, 2) a, b, c = Point(0, 0), Point(2, 0), Point(3, 3) t = Triangle(a, b, c) assert Polygon(a, Point(1, 0), b, c) == t assert Polygon(Point(1, 0), b, c, a) == t assert Polygon(b, c, a, Point(1, 0)) == t # 2 "remove folded" tests assert Polygon(a, Point(3, 0), b, c) == t assert Polygon(a, b, Point(3, -1), b, c) == t # remove multiple collinear points assert Polygon(Point(-4, 15), Point(-11, 15), Point(-15, 15), Point(-15, 33/5), Point(-15, -87/10), Point(-15, -15), Point(-42/5, -15), Point(-2, -15), Point(7, -15), Point(15, -15), Point(15, -3), Point(15, 10), Point(15, 15)) == \ Polygon(Point(-15,-15), Point(15,-15), Point(15,15), Point(-15,15)) p1 = Polygon( Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon( Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon( Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon( Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon( Point(0, 0), Point(4, 4), Point(0, 4)) p6 = Polygon( Point(-11, 1), Point(-9, 6.6), Point(-4, -3), Point(-8.4, -8.7)) p7 = Polygon( Point(x, y), Point(q, u), Point(v, w)) p8 = Polygon( Point(x, y), Point(v, w), Point(q, u)) p9 = Polygon( Point(0, 0), Point(4, 4), Point(3, 0), Point(5, 2)) p10 = Polygon( Point(0, 2), Point(2, 2), Point(0, 0), Point(2, 0)) p11 = Polygon(Point(0, 0), 1, n=3) r = Ray(Point(-9,6.6), Point(-9,5.5)) # # General polygon # assert p1 == p2 assert len(p1.args) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2*sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert Polygon((-1, 1), (2, -1), (2, 1), (-1, -1), (3, 0) ).is_convex() is False # ensure convex for both CW and CCW point specification assert p3.is_convex() assert p4.is_convex() dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) is None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) is False assert p5.encloses_point(Point(4, 0)) is False assert p1.encloses(Circle(Point(2.5,2.5),5)) is False assert p1.encloses(Ellipse(Point(2.5,2),5,6)) is False p5.plot_interval('x') == [x, 0, 1] assert p5.distance( Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance( Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 with warns(UserWarning, \ match="Polygons may intersect producing erroneous output"): Polygon(Point(0, 0), Point(1, 0), Point(1, 1)).distance( Polygon(Point(0, 0), Point(0, 1), Point(1, 1))) assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert hash(p1) == hash(p2) assert hash(p7) == hash(p8) assert hash(p3) != hash(p9) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point('t').subs(Symbol('t', real=True), 0) == \ Point(0, 0) raises(ValueError, lambda: Polygon( Point(x, 0), Point(0, y), Point(x, y)).arbitrary_point('x')) assert p6.intersection(r) == [Point(-9, -S(84)/13), Point(-9, S(33)/5)] assert p10.area == 0 assert p11 == RegularPolygon(Point(0, 0), 1, 3, 0) assert p11.vertices[0] == Point(1, 0) assert p11.args[0] == Point(0, 0) p11.spin(pi/2) assert p11.vertices[0] == Point(0, 1) # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), 1, 2)) raises(ValueError, lambda: RegularPolygon(Point(0, 0), 1, 2.5)) assert p1 != p2 assert p1.interior_angle == 3*pi/5 assert p1.exterior_angle == 2*pi/5 assert p2.apothem == 5*cos(pi/5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) is False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi/3) assert p1.rotation == pi/3 assert p1.vertices[0] == Point(5, 5*sqrt(3)) for var in p1.args: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi/3) == RegularPolygon(Point(0, 0), 10, 5, 2*pi/3) assert p1 == p1_old assert p1.area == (-250*sqrt(5) + 1250)/(4*tan(pi/5)) assert p1.length == 20*sqrt(-sqrt(5)/8 + S(5)/8) assert p1.scale(2, 2) == \ RegularPolygon(p1.center, p1.radius*2, p1._n, p1.rotation) assert RegularPolygon((0, 0), 1, 4).scale(2, 3) == \ Polygon(Point(2, 0), Point(0, 3), Point(-2, 0), Point(0, -3)) assert repr(p1) == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, lambda: Triangle(Point(0, 0))) # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2*2, p2*3) == Segment(p2, p2*3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() is False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf()/2) assert t1.is_equilateral() is False assert t2.is_equilateral() assert t3.is_equilateral() is False assert are_similar(t1, t2) is False assert are_similar(t1, t3) assert are_similar(t2, t3) is False assert t1.is_similar(Point(0, 0)) is False assert t1.is_similar(t2) is False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment( p1, Point(Rational(5, 2), Rational(5, 2))) assert t2.bisectors()[p2] == Segment( Point(5, 0), Point(Rational(5, 4), 5*sqrt(3)/4)) p4 = Point(0, x1) assert t3.bisectors()[p4] == Segment(p4, Point(x1*(sqrt(2) - 1), 0)) ic = (250 - 125*sqrt(2))/50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5*sqrt(2)/2 assert t2.inradius == t2.incircle.radius == 5*sqrt(3)/6 assert t3.inradius == t3.incircle.radius == x1**2/((2 + sqrt(2))*Abs(x1)) # Exradius assert t1.exradii[t1.sides[2]] == 5*sqrt(2)/2 # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1/2, x1/2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Nine-point circle assert t1.nine_point_circle == Circle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) assert t1.nine_point_circle == Circle(Point(0, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2].equals(s1[0]) assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 t = S('''Triangle( Point(100080156402737/5000000000000, 79782624633431/500000000000), Point(39223884078253/2000000000000, 156345163124289/1000000000000), Point(31241359188437/1250000000000, 338338270939941/1000000000000000))''') assert t.orthocenter == S('''Point(-780660869050599840216997''' '''79471538701955848721853/80368430960602242240789074233100000000000000,''' '''20151573611150265741278060334545897615974257/16073686192120448448157''' '''8148466200000000000)''') # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon( Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5)/4), Point(1, Rational(5)/4), Point(1, Rational(9)/4), Point(0, Rational(9)/4)) p3 = Polygon( Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon( Point(1, 1), Point(Rational(6)/5, 1), Point(1, Rational(6)/5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3)/4 assert p3.distance(pt2) == sqrt(2)/2 '''Polygon to Polygon''' # p1.distance(p2) emits a warning with warns(UserWarning, \ match="Polygons may intersect producing erroneous output"): assert p1.distance(p2) == half/2 assert p1.distance(p3) == sqrt(2)/2 # p3.distance(p4) emits a warning with warns(UserWarning, \ match="Polygons may intersect producing erroneous output"): assert p3.distance(p4) == (sqrt(2)/2 - sqrt(Rational(2)/25)/2)
def test_intersection(): poly1 = Triangle(Point(0, 0), Point(1, 0), Point(0, 1)) poly2 = Polygon(Point(0, 1), Point(-5, 0), Point(0, -4), Point(0, S(1)/5), Point(S(1)/2, -0.1), Point(1,0), Point(0, 1)) assert poly1.intersection(poly2) == [Point2D(S(1)/3, 0), Segment(Point(0, S(1)/5), Point(0, 0)), Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(poly1) == [Point(S(1)/3, 0), Segment(Point(0, 0), Point(0, S(1)/5)), Segment(Point(1, 0), Point(0, 1))] assert poly1.intersection(Point(0, 0)) == [Point(0, 0)] assert poly1.intersection(Point(-12, -43)) == [] assert poly2.intersection(Line((-12, 0), (12, 0))) == [Point(-5, 0), Point(0, 0),Point(S(1)/3, 0), Point(1, 0)] assert poly2.intersection(Line((-12, 12), (12, 12))) == [] assert poly2.intersection(Ray((-3,4), (1,0))) == [Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(Circle((0, -1), 1)) == [Point(0, -2), Point(0, 0)] assert poly1.intersection(poly1) == [Segment(Point(0, 0), Point(1, 0)), Segment(Point(0, 1), Point(0, 0)), Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(poly2) == [Segment(Point(-5, 0), Point(0, -4)), Segment(Point(0, -4), Point(0, S(1)/5)), Segment(Point(0, S(1)/5), Point(S(1)/2, -S(1)/10)), Segment(Point(0, 1), Point(-5, 0)), Segment(Point(S(1)/2, -S(1)/10), Point(1, 0)), Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(Triangle(Point(0, 1), Point(1, 0), Point(-1, 1))) \ == [Point(-S(5)/7, S(6)/7), Segment(Point2D(0, 1), Point(1, 0))] assert poly1.intersection(RegularPolygon((-12, -15), 3, 3)) == []
def test_convex_hull(): p = [Point(-5, -1), Point(-2, 1), Point(-2, -1), Point(-1, -3), \ Point(0, 0), Point(1, 1), Point(2, 2), Point(2, -1), Point(3, 1), \ Point(4, -1), Point(6, 2)] ch = Polygon(p[0], p[3], p[9], p[10], p[6], p[1]) #test handling of duplicate points p.append(p[3]) #more than 3 collinear points another_p = [Point(-45, -85), Point(-45, 85), Point(-45, 26), \ Point(-45, -24)] ch2 = Segment(another_p[0], another_p[1]) assert convex_hull(*another_p) == ch2 assert convex_hull(*p) == ch assert convex_hull(p[0]) == p[0] assert convex_hull(p[0], p[1]) == Segment(p[0], p[1]) # no unique points assert convex_hull(*[p[-1]]*3) == p[-1] # collection of items assert convex_hull(*[Point(0, 0), \ Segment(Point(1, 0), Point(1, 1)), \ RegularPolygon(Point(2, 0), 2, 4)]) == \ Polygon(Point(0, 0), Point(2, -2), Point(4, 0), Point(2, 2))
def centroid(*args): """Find the centroid (center of mass) of the collection containing only Points, Segments or Polygons. The centroid is the weighted average of the individual centroid where the weights are the lengths (of segments) or areas (of polygons). Overlapping regions will add to the weight of that region. If there are no objects (or a mixture of objects) then None is returned. See Also ======== sympy.geometry.point.Point, sympy.geometry.line.Segment, sympy.geometry.polygon.Polygon Examples ======== >>> from sympy import Point, Segment, Polygon >>> from sympy.geometry.util import centroid >>> p = Polygon((0, 0), (10, 0), (10, 10)) >>> q = p.translate(0, 20) >>> p.centroid, q.centroid (Point2D(20/3, 10/3), Point2D(20/3, 70/3)) >>> centroid(p, q) Point2D(20/3, 40/3) >>> p, q = Segment((0, 0), (2, 0)), Segment((0, 0), (2, 2)) >>> centroid(p, q) Point2D(1, -sqrt(2) + 2) >>> centroid(Point(0, 0), Point(2, 0)) Point2D(1, 0) Stacking 3 polygons on top of each other effectively triples the weight of that polygon: >>> p = Polygon((0, 0), (1, 0), (1, 1), (0, 1)) >>> q = Polygon((1, 0), (3, 0), (3, 1), (1, 1)) >>> centroid(p, q) Point2D(3/2, 1/2) >>> centroid(p, p, p, q) # centroid x-coord shifts left Point2D(11/10, 1/2) Stacking the squares vertically above and below p has the same effect: >>> centroid(p, p.translate(0, 1), p.translate(0, -1), q) Point2D(11/10, 1/2) """ from sympy.geometry import Polygon, Segment, Point if args: if all(isinstance(g, Point) for g in args): c = Point(0, 0) for g in args: c += g den = len(args) elif all(isinstance(g, Segment) for g in args): c = Point(0, 0) L = 0 for g in args: l = g.length c += g.midpoint * l L += l den = L elif all(isinstance(g, Polygon) for g in args): c = Point(0, 0) A = 0 for g in args: a = g.area c += g.centroid * a A += a den = A c /= den return c.func(*[i.simplify() for i in c.args])
def test_transform(): pts = [Point(0, 0), Point(S(1)/2, S(1)/4), Point(1, 1)] pts_out = [Point(-4, -10), Point(-3, -S(37)/4), Point(-2, -7)] assert Triangle(*pts).scale(2, 3, (4, 5)) == Triangle(*pts_out) assert RegularPolygon((0, 0), 1, 4).scale(2, 3, (4, 5)) == \ Polygon(Point(-2, -10), Point(-4, -7), Point(-6, -10), Point(-4, -13))
def intersection(*entities, **kwargs): """The intersection of a collection of GeometryEntity instances. Parameters ========== entities : sequence of GeometryEntity pairwise (keyword argument) : Can be either True or False Returns ======= intersection : list of GeometryEntity Raises ====== NotImplementedError When unable to calculate intersection. Notes ===== The intersection of any geometrical entity with itself should return a list with one item: the entity in question. An intersection requires two or more entities. If only a single entity is given then the function will return an empty list. It is possible for `intersection` to miss intersections that one knows exists because the required quantities were not fully simplified internally. Reals should be converted to Rationals, e.g. Rational(str(real_num)) or else failures due to floating point issues may result. Case 1: When the keyword argument 'pairwise' is False (default value): In this case, the functon returns a list of intersections common to all entities. Case 2: When the keyword argument 'pairwise' is True: In this case, the functions returns a list intersections that occur between any pair of entities. See Also ======== sympy.geometry.entity.GeometryEntity.intersection Examples ======== >>> from sympy.geometry import Ray, Circle, intersection >>> c = Circle((0, 1), 1) >>> intersection(c, c.center) [] >>> right = Ray((0, 0), (1, 0)) >>> up = Ray((0, 0), (0, 1)) >>> intersection(c, right, up) [Point2D(0, 0)] >>> intersection(c, right, up, pairwise=True) [Point2D(0, 0), Point2D(0, 2)] >>> left = Ray((1, 0), (0, 0)) >>> intersection(right, left) [Segment2D(Point2D(0, 0), Point2D(1, 0))] """ from .entity import GeometryEntity from .point import Point pairwise = kwargs.pop('pairwise', False) if len(entities) <= 1: return [] # entities may be an immutable tuple entities = list(entities) for i, e in enumerate(entities): if not isinstance(e, GeometryEntity): entities[i] = Point(e) if not pairwise: # find the intersection common to all objects res = entities[0].intersection(entities[1]) for entity in entities[2:]: newres = [] for x in res: newres.extend(x.intersection(entity)) res = newres return res # find all pairwise intersections ans = [] for j in range(0, len(entities)): for k in range(j + 1, len(entities)): ans.extend(intersection(entities[j], entities[k])) return list(ordered(set(ans)))
from numpy import pi, linspace, array from scipy.special import ellipeinc from sympy import Symbol, solve, sqrt from sympy.geometry import Point, Ellipse from subprocess import check_output chestData = check_output(["Rscript", "bodydata.r"], shell=True) chestData = chestData.decode("UTF-8") chestData = json.loads(chestData.splitlines()[0]) rc_min = chestData[0] rc_max = chestData[1] a = int(chestData[2]['mean']) b = int(chestData[3]['mean']) # MOMENT 0 e0 = Ellipse(Point(0, 0), hradius=a, vradius=b) P = e0.circumference E = e0.eccentricity theta = Symbol('theta') x = Symbol('x') y = Symbol('y') P = pi * (3 * (x + y) - sqrt((3 * x + y) * (x + 3 * y))) - P x1, x2 = solve(P, x) def radius_of_curvature(ellipse, points): a = ellipse.hradius b = ellipse.vradius rho_ellipse = [] for i in range(len(points)):