123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- from sympy.core.basic import Basic
- from sympy.core.numbers import (I, Rational, pi)
- from sympy.core.parameters import evaluate
- from sympy.core.singleton import S
- from sympy.core.symbol import Symbol
- from sympy.core.sympify import sympify
- from sympy.functions.elementary.miscellaneous import sqrt
- from sympy.geometry import Line, Point, Point2D, Point3D, Line3D, Plane
- from sympy.geometry.entity import rotate, scale, translate, GeometryEntity
- from sympy.matrices import Matrix
- from sympy.utilities.iterables import subsets, permutations, cartes
- from sympy.utilities.misc import Undecidable
- from sympy.testing.pytest import raises, warns
- def test_point():
- x = Symbol('x', real=True)
- y = Symbol('y', real=True)
- x1 = Symbol('x1', real=True)
- x2 = Symbol('x2', real=True)
- y1 = Symbol('y1', real=True)
- y2 = Symbol('y2', real=True)
- half = S.Half
- p1 = Point(x1, x2)
- p2 = Point(y1, y2)
- p3 = Point(0, 0)
- p4 = Point(1, 1)
- p5 = Point(0, 1)
- line = Line(Point(1, 0), slope=1)
- assert p1 in p1
- assert p1 not in p2
- assert p2.y == y2
- assert (p3 + p4) == p4
- assert (p2 - p1) == Point(y1 - x1, y2 - x2)
- assert -p2 == Point(-y1, -y2)
- raises(TypeError, lambda: Point(1))
- raises(ValueError, lambda: Point([1]))
- raises(ValueError, lambda: Point(3, I))
- raises(ValueError, lambda: Point(2*I, I))
- raises(ValueError, lambda: Point(3 + I, I))
- assert Point(34.05, sqrt(3)) == Point(Rational(681, 20), sqrt(3))
- assert Point.midpoint(p3, p4) == Point(half, half)
- assert Point.midpoint(p1, p4) == Point(half + half*x1, half + half*x2)
- assert Point.midpoint(p2, p2) == p2
- assert p2.midpoint(p2) == p2
- assert p1.origin == Point(0, 0)
- assert Point.distance(p3, p4) == sqrt(2)
- assert Point.distance(p1, p1) == 0
- assert Point.distance(p3, p2) == sqrt(p2.x**2 + p2.y**2)
- raises(TypeError, lambda: Point.distance(p1, 0))
- raises(TypeError, lambda: Point.distance(p1, GeometryEntity()))
- # distance should be symmetric
- assert p1.distance(line) == line.distance(p1)
- assert p4.distance(line) == line.distance(p4)
- assert Point.taxicab_distance(p4, p3) == 2
- assert Point.canberra_distance(p4, p5) == 1
- raises(ValueError, lambda: Point.canberra_distance(p3, p3))
- p1_1 = Point(x1, x1)
- p1_2 = Point(y2, y2)
- p1_3 = Point(x1 + 1, x1)
- assert Point.is_collinear(p3)
- with warns(UserWarning, test_stacklevel=False):
- assert Point.is_collinear(p3, Point(p3, dim=4))
- assert p3.is_collinear()
- assert Point.is_collinear(p3, p4)
- assert Point.is_collinear(p3, p4, p1_1, p1_2)
- assert Point.is_collinear(p3, p4, p1_1, p1_3) is False
- assert Point.is_collinear(p3, p3, p4, p5) is False
- raises(TypeError, lambda: Point.is_collinear(line))
- raises(TypeError, lambda: p1_1.is_collinear(line))
- assert p3.intersection(Point(0, 0)) == [p3]
- assert p3.intersection(p4) == []
- assert p3.intersection(line) == []
- with warns(UserWarning, test_stacklevel=False):
- assert Point.intersection(Point(0, 0, 0), Point(0, 0)) == [Point(0, 0, 0)]
- x_pos = Symbol('x', positive=True)
- p2_1 = Point(x_pos, 0)
- p2_2 = Point(0, x_pos)
- p2_3 = Point(-x_pos, 0)
- p2_4 = Point(0, -x_pos)
- p2_5 = Point(x_pos, 5)
- assert Point.is_concyclic(p2_1)
- assert Point.is_concyclic(p2_1, p2_2)
- assert Point.is_concyclic(p2_1, p2_2, p2_3, p2_4)
- for pts in permutations((p2_1, p2_2, p2_3, p2_5)):
- assert Point.is_concyclic(*pts) is False
- assert Point.is_concyclic(p4, p4 * 2, p4 * 3) is False
- assert Point(0, 0).is_concyclic((1, 1), (2, 2), (2, 1)) is False
- assert Point.is_concyclic(Point(0, 0, 0, 0), Point(1, 0, 0, 0), Point(1, 1, 0, 0), Point(1, 1, 1, 0)) is False
- assert p1.is_scalar_multiple(p1)
- assert p1.is_scalar_multiple(2*p1)
- assert not p1.is_scalar_multiple(p2)
- assert Point.is_scalar_multiple(Point(1, 1), (-1, -1))
- assert Point.is_scalar_multiple(Point(0, 0), (0, -1))
- # test when is_scalar_multiple can't be determined
- raises(Undecidable, lambda: Point.is_scalar_multiple(Point(sympify("x1%y1"), sympify("x2%y2")), Point(0, 1)))
- assert Point(0, 1).orthogonal_direction == Point(1, 0)
- assert Point(1, 0).orthogonal_direction == Point(0, 1)
- assert p1.is_zero is None
- assert p3.is_zero
- assert p4.is_zero is False
- assert p1.is_nonzero is None
- assert p3.is_nonzero is False
- assert p4.is_nonzero
- assert p4.scale(2, 3) == Point(2, 3)
- assert p3.scale(2, 3) == p3
- assert p4.rotate(pi, Point(0.5, 0.5)) == p3
- assert p1.__radd__(p2) == p1.midpoint(p2).scale(2, 2)
- assert (-p3).__rsub__(p4) == p3.midpoint(p4).scale(2, 2)
- assert p4 * 5 == Point(5, 5)
- assert p4 / 5 == Point(0.2, 0.2)
- assert 5 * p4 == Point(5, 5)
- raises(ValueError, lambda: Point(0, 0) + 10)
- # Point differences should be simplified
- assert Point(x*(x - 1), y) - Point(x**2 - x, y + 1) == Point(0, -1)
- a, b = S.Half, Rational(1, 3)
- assert Point(a, b).evalf(2) == \
- Point(a.n(2), b.n(2), evaluate=False)
- raises(ValueError, lambda: Point(1, 2) + 1)
- # test project
- assert Point.project((0, 1), (1, 0)) == Point(0, 0)
- assert Point.project((1, 1), (1, 0)) == Point(1, 0)
- raises(ValueError, lambda: Point.project(p1, Point(0, 0)))
- # test transformations
- p = Point(1, 0)
- assert p.rotate(pi/2) == Point(0, 1)
- assert p.rotate(pi/2, p) == p
- p = Point(1, 1)
- assert p.scale(2, 3) == Point(2, 3)
- assert p.translate(1, 2) == Point(2, 3)
- assert p.translate(1) == Point(2, 1)
- assert p.translate(y=1) == Point(1, 2)
- assert p.translate(*p.args) == Point(2, 2)
- # Check invalid input for transform
- raises(ValueError, lambda: p3.transform(p3))
- raises(ValueError, lambda: p.transform(Matrix([[1, 0], [0, 1]])))
- # test __contains__
- assert 0 in Point(0, 0, 0, 0)
- assert 1 not in Point(0, 0, 0, 0)
- # test affine_rank
- assert Point.affine_rank() == -1
- def test_point3D():
- x = Symbol('x', real=True)
- y = Symbol('y', real=True)
- x1 = Symbol('x1', real=True)
- x2 = Symbol('x2', real=True)
- x3 = Symbol('x3', real=True)
- y1 = Symbol('y1', real=True)
- y2 = Symbol('y2', real=True)
- y3 = Symbol('y3', real=True)
- half = S.Half
- p1 = Point3D(x1, x2, x3)
- p2 = Point3D(y1, y2, y3)
- p3 = Point3D(0, 0, 0)
- p4 = Point3D(1, 1, 1)
- p5 = Point3D(0, 1, 2)
- assert p1 in p1
- assert p1 not in p2
- assert p2.y == y2
- assert (p3 + p4) == p4
- assert (p2 - p1) == Point3D(y1 - x1, y2 - x2, y3 - x3)
- assert -p2 == Point3D(-y1, -y2, -y3)
- assert Point(34.05, sqrt(3)) == Point(Rational(681, 20), sqrt(3))
- assert Point3D.midpoint(p3, p4) == Point3D(half, half, half)
- assert Point3D.midpoint(p1, p4) == Point3D(half + half*x1, half + half*x2,
- half + half*x3)
- assert Point3D.midpoint(p2, p2) == p2
- assert p2.midpoint(p2) == p2
- assert Point3D.distance(p3, p4) == sqrt(3)
- assert Point3D.distance(p1, p1) == 0
- assert Point3D.distance(p3, p2) == sqrt(p2.x**2 + p2.y**2 + p2.z**2)
- p1_1 = Point3D(x1, x1, x1)
- p1_2 = Point3D(y2, y2, y2)
- p1_3 = Point3D(x1 + 1, x1, x1)
- Point3D.are_collinear(p3)
- assert Point3D.are_collinear(p3, p4)
- assert Point3D.are_collinear(p3, p4, p1_1, p1_2)
- assert Point3D.are_collinear(p3, p4, p1_1, p1_3) is False
- assert Point3D.are_collinear(p3, p3, p4, p5) is False
- assert p3.intersection(Point3D(0, 0, 0)) == [p3]
- assert p3.intersection(p4) == []
- assert p4 * 5 == Point3D(5, 5, 5)
- assert p4 / 5 == Point3D(0.2, 0.2, 0.2)
- assert 5 * p4 == Point3D(5, 5, 5)
- raises(ValueError, lambda: Point3D(0, 0, 0) + 10)
- # Test coordinate properties
- assert p1.coordinates == (x1, x2, x3)
- assert p2.coordinates == (y1, y2, y3)
- assert p3.coordinates == (0, 0, 0)
- assert p4.coordinates == (1, 1, 1)
- assert p5.coordinates == (0, 1, 2)
- assert p5.x == 0
- assert p5.y == 1
- assert p5.z == 2
- # Point differences should be simplified
- assert Point3D(x*(x - 1), y, 2) - Point3D(x**2 - x, y + 1, 1) == \
- Point3D(0, -1, 1)
- a, b, c = S.Half, Rational(1, 3), Rational(1, 4)
- assert Point3D(a, b, c).evalf(2) == \
- Point(a.n(2), b.n(2), c.n(2), evaluate=False)
- raises(ValueError, lambda: Point3D(1, 2, 3) + 1)
- # test transformations
- p = Point3D(1, 1, 1)
- assert p.scale(2, 3) == Point3D(2, 3, 1)
- assert p.translate(1, 2) == Point3D(2, 3, 1)
- assert p.translate(1) == Point3D(2, 1, 1)
- assert p.translate(z=1) == Point3D(1, 1, 2)
- assert p.translate(*p.args) == Point3D(2, 2, 2)
- # Test __new__
- assert Point3D(0.1, 0.2, evaluate=False, on_morph='ignore').args[0].is_Float
- # Test length property returns correctly
- assert p.length == 0
- assert p1_1.length == 0
- assert p1_2.length == 0
- # Test are_colinear type error
- raises(TypeError, lambda: Point3D.are_collinear(p, x))
- # Test are_coplanar
- assert Point.are_coplanar()
- assert Point.are_coplanar((1, 2, 0), (1, 2, 0), (1, 3, 0))
- assert Point.are_coplanar((1, 2, 0), (1, 2, 3))
- with warns(UserWarning, test_stacklevel=False):
- raises(ValueError, lambda: Point2D.are_coplanar((1, 2), (1, 2, 3)))
- assert Point3D.are_coplanar((1, 2, 0), (1, 2, 3))
- assert Point.are_coplanar((0, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 1)) is False
- planar2 = Point3D(1, -1, 1)
- planar3 = Point3D(-1, 1, 1)
- assert Point3D.are_coplanar(p, planar2, planar3) == True
- assert Point3D.are_coplanar(p, planar2, planar3, p3) == False
- assert Point.are_coplanar(p, planar2)
- planar2 = Point3D(1, 1, 2)
- planar3 = Point3D(1, 1, 3)
- assert Point3D.are_coplanar(p, planar2, planar3) # line, not plane
- plane = Plane((1, 2, 1), (2, 1, 0), (3, 1, 2))
- assert Point.are_coplanar(*[plane.projection(((-1)**i, i)) for i in range(4)])
- # all 2D points are coplanar
- assert Point.are_coplanar(Point(x, y), Point(x, x + y), Point(y, x + 2)) is True
- # Test Intersection
- assert planar2.intersection(Line3D(p, planar3)) == [Point3D(1, 1, 2)]
- # Test Scale
- assert planar2.scale(1, 1, 1) == planar2
- assert planar2.scale(2, 2, 2, planar3) == Point3D(1, 1, 1)
- assert planar2.scale(1, 1, 1, p3) == planar2
- # Test Transform
- identity = Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
- assert p.transform(identity) == p
- trans = Matrix([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], [0, 0, 0, 1]])
- assert p.transform(trans) == Point3D(2, 2, 2)
- raises(ValueError, lambda: p.transform(p))
- raises(ValueError, lambda: p.transform(Matrix([[1, 0], [0, 1]])))
- # Test Equals
- assert p.equals(x1) == False
- # Test __sub__
- p_4d = Point(0, 0, 0, 1)
- with warns(UserWarning, test_stacklevel=False):
- assert p - p_4d == Point(1, 1, 1, -1)
- p_4d3d = Point(0, 0, 1, 0)
- with warns(UserWarning, test_stacklevel=False):
- assert p - p_4d3d == Point(1, 1, 0, 0)
- def test_Point2D():
- # Test Distance
- p1 = Point2D(1, 5)
- p2 = Point2D(4, 2.5)
- p3 = (6, 3)
- assert p1.distance(p2) == sqrt(61)/2
- assert p2.distance(p3) == sqrt(17)/2
- # Test coordinates
- assert p1.x == 1
- assert p1.y == 5
- assert p2.x == 4
- assert p2.y == S(5)/2
- assert p1.coordinates == (1, 5)
- assert p2.coordinates == (4, S(5)/2)
- # test bounds
- assert p1.bounds == (1, 5, 1, 5)
- def test_issue_9214():
- p1 = Point3D(4, -2, 6)
- p2 = Point3D(1, 2, 3)
- p3 = Point3D(7, 2, 3)
- assert Point3D.are_collinear(p1, p2, p3) is False
- def test_issue_11617():
- p1 = Point3D(1,0,2)
- p2 = Point2D(2,0)
- with warns(UserWarning, test_stacklevel=False):
- assert p1.distance(p2) == sqrt(5)
- def test_transform():
- p = Point(1, 1)
- assert p.transform(rotate(pi/2)) == Point(-1, 1)
- assert p.transform(scale(3, 2)) == Point(3, 2)
- assert p.transform(translate(1, 2)) == Point(2, 3)
- assert Point(1, 1).scale(2, 3, (4, 5)) == \
- Point(-2, -7)
- assert Point(1, 1).translate(4, 5) == \
- Point(5, 6)
- def test_concyclic_doctest_bug():
- p1, p2 = Point(-1, 0), Point(1, 0)
- p3, p4 = Point(0, 1), Point(-1, 2)
- assert Point.is_concyclic(p1, p2, p3)
- assert not Point.is_concyclic(p1, p2, p3, p4)
- def test_arguments():
- """Functions accepting `Point` objects in `geometry`
- should also accept tuples and lists and
- automatically convert them to points."""
- singles2d = ((1,2), [1,2], Point(1,2))
- singles2d2 = ((1,3), [1,3], Point(1,3))
- doubles2d = cartes(singles2d, singles2d2)
- p2d = Point2D(1,2)
- singles3d = ((1,2,3), [1,2,3], Point(1,2,3))
- doubles3d = subsets(singles3d, 2)
- p3d = Point3D(1,2,3)
- singles4d = ((1,2,3,4), [1,2,3,4], Point(1,2,3,4))
- doubles4d = subsets(singles4d, 2)
- p4d = Point(1,2,3,4)
- # test 2D
- test_single = ['distance', 'is_scalar_multiple', 'taxicab_distance', 'midpoint', 'intersection', 'dot', 'equals', '__add__', '__sub__']
- test_double = ['is_concyclic', 'is_collinear']
- for p in singles2d:
- Point2D(p)
- for func in test_single:
- for p in singles2d:
- getattr(p2d, func)(p)
- for func in test_double:
- for p in doubles2d:
- getattr(p2d, func)(*p)
- # test 3D
- test_double = ['is_collinear']
- for p in singles3d:
- Point3D(p)
- for func in test_single:
- for p in singles3d:
- getattr(p3d, func)(p)
- for func in test_double:
- for p in doubles3d:
- getattr(p3d, func)(*p)
- # test 4D
- test_double = ['is_collinear']
- for p in singles4d:
- Point(p)
- for func in test_single:
- for p in singles4d:
- getattr(p4d, func)(p)
- for func in test_double:
- for p in doubles4d:
- getattr(p4d, func)(*p)
- # test evaluate=False for ops
- x = Symbol('x')
- a = Point(0, 1)
- assert a + (0.1, x) == Point(0.1, 1 + x, evaluate=False)
- a = Point(0, 1)
- assert a/10.0 == Point(0, 0.1, evaluate=False)
- a = Point(0, 1)
- assert a*10.0 == Point(0.0, 10.0, evaluate=False)
- # test evaluate=False when changing dimensions
- u = Point(.1, .2, evaluate=False)
- u4 = Point(u, dim=4, on_morph='ignore')
- assert u4.args == (.1, .2, 0, 0)
- assert all(i.is_Float for i in u4.args[:2])
- # and even when *not* changing dimensions
- assert all(i.is_Float for i in Point(u).args)
- # never raise error if creating an origin
- assert Point(dim=3, on_morph='error')
- # raise error with unmatched dimension
- raises(ValueError, lambda: Point(1, 1, dim=3, on_morph='error'))
- # test unknown on_morph
- raises(ValueError, lambda: Point(1, 1, dim=3, on_morph='unknown'))
- # test invalid expressions
- raises(TypeError, lambda: Point(Basic(), Basic()))
- def test_unit():
- assert Point(1, 1).unit == Point(sqrt(2)/2, sqrt(2)/2)
- def test_dot():
- raises(TypeError, lambda: Point(1, 2).dot(Line((0, 0), (1, 1))))
- def test__normalize_dimension():
- assert Point._normalize_dimension(Point(1, 2), Point(3, 4)) == [
- Point(1, 2), Point(3, 4)]
- assert Point._normalize_dimension(
- Point(1, 2), Point(3, 4, 0), on_morph='ignore') == [
- Point(1, 2, 0), Point(3, 4, 0)]
- def test_issue_22684():
- # Used to give an error
- with evaluate(False):
- Point(1, 2)
- def test_direction_cosine():
- p1 = Point3D(0, 0, 0)
- p2 = Point3D(1, 1, 1)
- assert p1.direction_cosine(Point3D(1, 0, 0)) == [1, 0, 0]
- assert p1.direction_cosine(Point3D(0, 1, 0)) == [0, 1, 0]
- assert p1.direction_cosine(Point3D(0, 0, pi)) == [0, 0, 1]
- assert p1.direction_cosine(Point3D(5, 0, 0)) == [1, 0, 0]
- assert p1.direction_cosine(Point3D(0, sqrt(3), 0)) == [0, 1, 0]
- assert p1.direction_cosine(Point3D(0, 0, 5)) == [0, 0, 1]
- assert p1.direction_cosine(Point3D(2.4, 2.4, 0)) == [sqrt(2)/2, sqrt(2)/2, 0]
- assert p1.direction_cosine(Point3D(1, 1, 1)) == [sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3]
- assert p1.direction_cosine(Point3D(-12, 0 -15)) == [-4*sqrt(41)/41, -5*sqrt(41)/41, 0]
- assert p2.direction_cosine(Point3D(0, 0, 0)) == [-sqrt(3) / 3, -sqrt(3) / 3, -sqrt(3) / 3]
- assert p2.direction_cosine(Point3D(1, 1, 12)) == [0, 0, 1]
- assert p2.direction_cosine(Point3D(12, 1, 12)) == [sqrt(2) / 2, 0, sqrt(2) / 2]
|