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, 0, -5 * sqrt(41) / 41] 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]
def test_point3D(): 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 p4 * 5 == Point3D(5, 5, 5) 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) # according to the description in the docs, points are collinear # if they like on a single line. Thus a single point should always # be collinear assert 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) pytest.raises(ValueError, lambda: Point3D(0, 0, 0) + 10) # 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 = Rational(1, 2), Rational(1, 3) assert Point(a, b).evalf(2) == \ Point(a.evalf(2), b.evalf(2)) pytest.raises(ValueError, lambda: Point(1, 2) + 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(Point3D(1, 2, 3), 4, 5, evaluate=False) == Point3D(1, 2, 3) # Test length property returns correctly assert p.length == 0 assert p1_1.length == 0 assert p1_2.length == 0 # Test are_colinear type error pytest.raises(TypeError, lambda: Point3D.are_collinear(p, x)) # Test are_coplanar planar2 = Point3D(1, -1, 1) planar3 = Point3D(-1, 1, 1) assert Point3D.are_coplanar(p, planar2, planar3) is True assert Point3D.are_coplanar(p, planar2, planar3, p3) is False pytest.raises(ValueError, lambda: Point3D.are_coplanar(p, planar2)) planar2 = Point3D(1, 1, 2) planar3 = Point3D(1, 1, 3) pytest.raises(ValueError, lambda: Point3D.are_coplanar(p, planar2, planar3)) # 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) pytest.raises(ValueError, lambda: p.transform(p)) pytest.raises(ValueError, lambda: p.transform(Matrix([[1, 0], [0, 1]]))) # Test Equals assert p.equals(x1) is False # Test __sub__ p_2d = Point(0, 0) pytest.raises(ValueError, lambda: (p - p_2d))
def test_sympyissue_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_plane(): p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(1, 2, 3) p4 = Point3D(x, x, x) p5 = Point3D(y, y, y) pl3 = Plane(p1, p2, p3) pl4 = Plane(p1, normal_vector=(1, 1, 1)) pl4b = Plane(p1, p2) pl5 = Plane(p3, normal_vector=(1, 2, 3)) pl6 = Plane(Point3D(2, 3, 7), normal_vector=(2, 2, 2)) pl7 = Plane(Point3D(1, -5, -6), normal_vector=(1, -2, 1)) l1 = Line3D(Point3D(5, 0, 0), Point3D(1, -1, 1)) l2 = Line3D(Point3D(0, -2, 0), Point3D(3, 1, 1)) l3 = Line3D(Point3D(0, -1, 0), Point3D(5, -1, 9)) assert Plane(p1, p2, p3) != Plane(p1, p3, p2) assert Plane(p1, p2, p3).is_coplanar(Plane(p1, p3, p2)) assert pl3 == Plane(Point3D(0, 0, 0), normal_vector=(1, -2, 1)) assert pl3 != pl4 assert pl4 == pl4b assert pl5 == Plane(Point3D(1, 2, 3), normal_vector=(1, 2, 3)) assert pl5.equation(x, y, z) == x + 2 * y + 3 * z - 14 assert pl3.equation(x, y, z) == x - 2 * y + z assert pl3.p1 == p1 assert pl4.p1 == p1 assert pl5.p1 == p3 assert pl4.normal_vector == (1, 1, 1) assert pl5.normal_vector == (1, 2, 3) assert p1 in pl3 assert p1 in pl4 assert p3 in pl5 assert pl3.projection(Point(0, 0)) == p1 p = pl3.projection(Point3D(1, 1, 0)) assert p == Point3D(7 / 6, 2 / 3, 1 / 6) assert p in pl3 l = pl3.projection_line(Line(Point(0, 0), Point(1, 1))) assert l == Line3D(Point3D(0, 0, 0), Point3D(7 / 6, 2 / 3, 1 / 6)) assert l in pl3 # get a segment that does not intersect the plane which is also # parallel to pl3's normal veector t = Dummy() r = pl3.random_point() a = pl3.perpendicular_line(r).arbitrary_point(t) s = Segment3D(a.subs(t, 1), a.subs(t, 2)) assert s.p1 not in pl3 and s.p2 not in pl3 assert pl3.projection_line(s).equals(r) assert pl3.projection_line(Segment(Point(1, 0), Point(1, 1))) == \ Segment3D(Point3D(5/6, 1/3, -1/6), Point3D(7/6, 2/3, 1/6)) assert pl6.projection_line(Ray(Point(1, 0), Point(1, 1))) == \ Ray3D(Point3D(14/3, 11/3, 11/3), Point3D(13/3, 13/3, 10/3)) assert pl3.perpendicular_line(r.args) == pl3.perpendicular_line(r) assert pl3.is_parallel(pl6) is False assert pl4.is_parallel(pl6) assert pl6.is_parallel(l1) is False assert pl3.is_perpendicular(pl6) assert pl4.is_perpendicular(pl7) assert pl6.is_perpendicular(pl7) assert pl6.is_perpendicular(l1) is False assert pl7.distance(Point3D(1, 3, 5)) == 5 * sqrt(6) / 6 assert pl6.distance(Point3D(0, 0, 0)) == 4 * sqrt(3) assert pl6.distance(pl6.p1) == 0 assert pl7.distance(pl6) == 0 assert pl7.distance(l1) == 0 assert pl6.distance(Segment3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == 0 pl6.distance(Plane(Point3D(5, 5, 5), normal_vector=(8, 8, 8))) == sqrt(3) assert pl6.angle_between(pl3) == pi / 2 assert pl6.angle_between(pl6) == 0 assert pl6.angle_between(pl4) == 0 assert pl7.angle_between(Line3D(Point3D(2, 3, 5), Point3D(2, 4, 6))) == \ -asin(sqrt(3)/6) assert pl6.angle_between(Ray3D(Point3D(2, 4, 1), Point3D(6, 5, 3))) == \ asin(sqrt(7)/3) assert pl7.angle_between(Segment3D(Point3D(5, 6, 1), Point3D(1, 2, 4))) == \ -asin(7*sqrt(246)/246) assert are_coplanar(l1, l2, l3) is False assert are_coplanar(l1) is False assert are_coplanar(Point3D(2, 7, 2), Point3D(0, 0, 2), Point3D(1, 1, 2), Point3D(1, 2, 2)) assert are_coplanar(Plane(p1, p2, p3), Plane(p1, p3, p2)) assert Plane.are_concurrent(pl3, pl4, pl5) is False assert Plane.are_concurrent(pl6) is False pytest.raises(ValueError, lambda: Plane.are_concurrent(Point3D(0, 0, 0))) assert pl3.parallel_plane(Point3D(1, 2, 5)) == Plane(Point3D(1, 2, 5), normal_vector=(1, -2, 1)) # perpendicular_plane p = Plane((0, 0, 0), (1, 0, 0)) # default assert p.perpendicular_plane() == Plane(Point3D(0, 0, 0), (0, 1, 0)) # 1 pt assert p.perpendicular_plane(Point3D(1, 0, 1)) == \ Plane(Point3D(1, 0, 1), (0, 1, 0)) # pts as tuples assert p.perpendicular_plane((1, 0, 1), (1, 1, 1)) == \ Plane(Point3D(1, 0, 1), (0, 0, -1)) a, b = Point3D(0, 0, 0), Point3D(0, 1, 0) Z = (0, 0, 1) p = Plane(a, normal_vector=Z) # case 4 assert p.perpendicular_plane(a, b) == Plane(a, (1, 0, 0)) n = Point3D(*Z) # case 1 assert p.perpendicular_plane(a, n) == Plane(a, (-1, 0, 0)) # case 2 assert Plane(a, normal_vector=b.args).perpendicular_plane(a, a + b) == \ Plane(Point3D(0, 0, 0), (1, 0, 0)) # case 1&3 assert Plane(b, normal_vector=Z).perpendicular_plane(b, b + n) == \ Plane(Point3D(0, 1, 0), (-1, 0, 0)) # case 2&3 assert Plane(b, normal_vector=b.args).perpendicular_plane(n, n + b) == \ Plane(Point3D(0, 0, 1), (1, 0, 0)) assert pl6.intersection(pl6) == [pl6] assert pl4.intersection(pl4.p1) == [pl4.p1] assert pl3.intersection(pl6) == [ Line3D(Point3D(8, 4, 0), Point3D(2, 4, 6)) ] assert pl3.intersection(Line3D(Point3D(1, 2, 4), Point3D(4, 4, 2))) == [Point3D(2, 8 / 3, 10 / 3)] assert pl3.intersection(Plane(Point3D(6, 0, 0), normal_vector=(2, -5, 3))) == [ Line3D(Point3D(-24, -12, 0), Point3D(-25, -13, -1)) ] assert pl6.intersection(Ray3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == [Point3D(-1, 3, 10)] assert pl6.intersection(Segment3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == [Point3D(-1, 3, 10)] assert pl7.intersection(Line(Point(2, 3), Point(4, 2))) == [Point3D(13 / 2, 3 / 4, 0)] r = Ray(Point(2, 3), Point(4, 2)) assert Plane((1, 2, 0), normal_vector=(0, 0, 1)).intersection(r) == [ Ray3D(Point(2, 3), Point(4, 2)) ] assert pl3.random_point() in pl3 # issue 8570 l2 = Line3D( Point3D(Rational(50000004459633, 5000000000000), Rational(-891926590718643, 1000000000000000), Rational(231800966893633, 100000000000000)), Point3D(Rational(50000004459633, 50000000000000), Rational(-222981647679771, 250000000000000), Rational(231800966893633, 100000000000000))) p2 = Plane( Point3D(Rational(402775636372767, 100000000000000), Rational(-97224357654973, 100000000000000), Rational(216793600814789, 100000000000000)), (-Float(9.00000087501922), Float(-4.81170658872543e-13), Float(0.0))) assert sstr([i.n(2) for i in p2.intersection(l2)]) == \ '[Point3D(4.0, -0.89, 2.3)]'
def test_line3d(): p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(x1, x1, x1) p4 = Point3D(y1, y1, y1) p5 = Point3D(x1, 1 + x1, 1) p6 = Point3D(1, 0, 1) l1 = Line3D(p1, p2) l2 = Line3D(p3, p4) l3 = Line3D(p3, p5) pytest.raises(ValueError, lambda: Line3D(Point3D(0, 0, 0), Point3D(0, 0, 0))) assert Line3D((1, 1, 1), direction_ratio=[2, 3, 4]) == \ Line3D(Point3D(1, 1, 1), Point3D(3, 4, 5)) assert Line3D((1, 1, 1), direction_ratio=[1, 5, 7 ]) == \ Line3D(Point3D(1, 1, 1), Point3D(2, 6, 8)) assert Line3D((1, 1, 1), direction_ratio=[1, 2, 3]) == \ Line3D(Point3D(1, 1, 1), Point3D(2, 3, 4)) pytest.raises(TypeError, lambda: Line3D((1, 1), 1)) assert Line3D(p1, p2) != Line3D(p2, p1) assert l1 != l3 assert l1.is_parallel(l1) # same as in 2D assert l1 != l2 assert l1.direction_ratio == [1, 1, 1] assert l1.length == oo assert l1.equation() == (x, y, z, k) assert l2.equation() == \ ((x - x1)/(-x1 + y1), (-x1 + y)/(-x1 + y1), (-x1 + z)/(-x1 + y1), k) assert p1 in l1 assert p1 not in l3 # Orthogonality p1_1 = Point3D(x1, x1, x1) l1_1 = Line3D(p1, p1_1) assert Line3D.is_perpendicular(l1, l2) is False p = l1.arbitrary_point() pytest.raises(NotImplementedError, lambda: l1.perpendicular_segment(p)) # Parallelity assert l1.parallel_line(p1_1) == Line3D(Point3D(x1, x1, x1), Point3D(x1 + 1, x1 + 1, x1 + 1)) assert l1.parallel_line(p1_1.args) == \ Line3D(Point3D(x1, x1, x1), Point3D(x1 + 1, x1 + 1, x1 + 1)) # Intersection assert intersection(l1, p1) == [p1] assert intersection(l1, p5) == [] assert intersection(l1, l1.parallel_line(p1)) == [ Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) ] # issue sympy/sympy#8517 line3 = Line3D(Point3D(4, 0, 1), Point3D(0, 4, 1)) line4 = Line3D(Point3D(0, 0, 1), Point3D(4, 4, 1)) assert line3.intersection(line4) == [Point3D(2, 2, 1)] assert line3.is_parallel(line4) is False assert Line3D((0, 1, 2), (0, 2, 3)).intersection(Line3D((0, 1, 2), (0, 1, 1))) == [] ray0 = Ray3D((0, 0), (3, 0)) ray1 = Ray3D((1, 0), (3, 0)) assert ray0.intersection(ray1) == [ray1] assert ray1.intersection(ray0) == [ray1] assert Segment3D((0, 0), (3, 0)).intersection(Segment3D( (1, 0), (2, 0))) == [Segment3D((1, 0), (2, 0))] assert Segment3D((1, 0), (2, 0)).intersection(Segment3D( (0, 0), (3, 0))) == [Segment3D((1, 0), (2, 0))] assert Segment3D((0, 0), (3, 0)).intersection(Segment3D( (3, 0), (4, 0))) == [Point3D((3, 0))] assert Segment3D((0, 0), (3, 0)).intersection(Segment3D( (2, 0), (5, 0))) == [Segment3D((3, 0), (2, 0))] assert Segment3D((0, 0), (3, 0)).intersection(Segment3D( (-2, 0), (1, 0))) == [Segment3D((0, 0), (1, 0))] assert Segment3D((0, 0), (3, 0)).intersection(Segment3D( (-2, 0), (0, 0))) == [Point3D(0, 0, 0)] # issue sympy/sympy#7757 p = Ray3D(Point3D(1, 0, 0), Point3D(-1, 0, 0)) q = Ray3D(Point3D(0, 1, 0), Point3D(0, -1, 0)) assert intersection(p, q) == [Point3D(0, 0, 0)] # Concurrency assert Line3D.are_concurrent(l1) is False assert Line3D.are_concurrent(l1, l2) assert Line3D.are_concurrent(l1, l1_1, l3) is False parallel_1 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)) parallel_2 = Line3D(Point3D(0, 1, 0), Point3D(1, 1, 0)) assert Line3D.are_concurrent(parallel_1, parallel_2) is False # Finding angles l1_1 = Line3D(p1, Point3D(5, 0, 0)) assert Line3D.angle_between(l1, l1_1), acos(sqrt(3) / 3) # Testing Rays and Segments (very similar to Lines) assert Ray3D((1, 1, 1), direction_ratio=[4, 4, 4]) == \ Ray3D(Point3D(1, 1, 1), Point3D(5, 5, 5)) assert Ray3D((1, 1, 1), direction_ratio=[1, 2, 3]) == \ Ray3D(Point3D(1, 1, 1), Point3D(2, 3, 4)) assert Ray3D((1, 1, 1), direction_ratio=[1, 1, 1]) == \ Ray3D(Point3D(1, 1, 1), Point3D(2, 2, 2)) r1 = Ray3D(p1, Point3D(-1, 5, 0)) r2 = Ray3D(p1, Point3D(-1, 1, 1)) r3 = Ray3D(p1, p2) r5 = Ray3D(Point3D(0, 1, 1), Point3D(1, 2, 0)) assert l1.projection(r1) == [ Ray3D(Point3D(0, 0, 0), Point3D(4 / 3, 4 / 3, 4 / 3)) ] assert l1.projection(r2) == [ Ray3D(Point3D(0, 0, 0), Point3D(1 / 3, 1 / 3, 1 / 3)) ] assert r3 != r1 t = Symbol('t', extended_real=True) assert Ray3D((1, 1, 1), direction_ratio=[1, 2, 3]).arbitrary_point() == \ Point3D(t + 1, 2*t + 1, 3*t + 1) r6 = Ray3D(Point3D(0, 0, 0), Point3D(0, 4, 0)) r7 = Ray3D(Point3D(0, 1, 1), Point3D(0, -1, 1)) assert r6.intersection(r7) == [] s1 = Segment3D(p1, p2) s2 = Segment3D(p3, p4) assert s1.midpoint == \ Point3D(Rational(1, 2), Rational(1, 2), Rational(1, 2)) assert s2.length == sqrt(3) * sqrt((x1 - y1)**2) assert Segment3D((1, 1, 1), (2, 3, 4)).arbitrary_point() == \ Point3D(t + 1, 2*t + 1, 3*t + 1) # Segment contains s = Segment3D((0, 1, 0), (0, 1, 0)) assert Point3D(0, 1, 0) in s s = Segment3D((1, 0, 0), (1, 0, 0)) assert Point3D(1, 0, 0) in s # Testing distance from a Segment to an object s1 = Segment3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) s2 = Segment3D(Point3D(1 / 2, 1 / 2, 1 / 2), Point3D(1, 0, 1)) pt1 = Point3D(0, 0, 0) pt2 = Point3D(Rational(3, 2), Rational(3, 2), Rational(3, 2)) assert s1.distance(pt1) == 0 assert s2.distance(pt1) == sqrt(3) / 2 assert s2.distance(pt2) == 2 assert s1.distance((0, 0, 0)) == 0 assert s2.distance((0, 0, 0)) == sqrt(3) / 2 # Line to point p1, p2 = Point3D(0, 0, 0), Point3D(1, 1, 1) s = Line3D(p1, p2) assert s.distance(Point3D(-1, 1, 1)) == 2 * sqrt(6) / 3 assert s.distance(Point3D(1, -1, 1)) == 2 * sqrt(6) / 3 assert s.distance(Point3D(2, 2, 2)) == 0 assert s.distance((2, 2, 2)) == 0 assert s.distance((1, -1, 1)) == 2 * sqrt(6) / 3 assert Line3D((0, 0, 0), (0, 1, 0)).distance(p1) == 0 assert Line3D((0, 0, 0), (0, 1, 0)).distance(p2) == sqrt(2) assert Line3D((0, 0, 0), (1, 0, 0)).distance(p1) == 0 assert Line3D((0, 0, 0), (1, 0, 0)).distance(p2) == sqrt(2) # Ray to point r = Ray3D(p1, p2) assert r.distance(Point3D(-1, -1, -1)) == sqrt(3) assert r.distance(Point3D(1, 1, 1)) == 0 assert r.distance((-1, -1, -1)) == sqrt(3) assert r.distance((1, 1, 1)) == 0 assert Ray3D((1, 1, 1), (2, 2, 2)).distance(Point3D(1.5, 3, 1)) == \ sqrt(17)/2 # Special cases of projection and intersection r1 = Ray3D(Point3D(1, 1, 1), Point3D(2, 2, 2)) r2 = Ray3D(Point3D(2, 2, 2), Point3D(0, 0, 0)) r3 = Ray3D(Point3D(1, 1, 1), Point3D(-1, -1, -1)) assert intersection(r1, r2) == \ [Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))] assert intersection(r1, r3) == [Point3D(1, 1, 1)] r5 = Ray3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) r6 = Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)) assert r5 in r6 assert r6 in r5 s1 = Segment3D(Point3D(0, 0, 0), Point3D(2, 2, 2)) s2 = Segment3D(Point3D(-1, 5, 2), Point3D(-5, -10, 0)) assert intersection(r1, s1) == [Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))] l1 = Line3D(Point3D(0, 0, 0), Point3D(3, 4, 0)) r1 = Ray3D(Point3D(0, 0, 0), Point3D(3, 4, 0)) s1 = Segment3D(Point3D(0, 0, 0), Point3D(3, 4, 0)) assert intersection(l1, r1) == [r1] assert intersection(l1, s1) == [s1] assert intersection(r1, l1) == [r1] assert intersection(s1, r1) == [s1] # check that temporary symbol is Dummy assert Line3D((0, 0), (t, t)).perpendicular_line((0, 1)) == \ Line3D(Point3D(0, 1, 0), Point3D(1/2, 1/2, 0)) assert Line3D((0, 0), (t, t)).perpendicular_segment((0, 1)) == \ Segment3D(Point3D(0, 1, 0), Point3D(1/2, 1/2, 0)) assert Line3D((0, 0), (t, t)).intersection(Line3D((0, 1), (t, t))) == \ [Point3D(t, t, 0)] assert Line3D((0, 0, 0), (x, y, z)).contains((2 * x, 2 * y, 2 * z)) # Test is_perpendicular perp_1 = Line3D(p1, Point3D(0, 1, 0)) assert Line3D.is_perpendicular(parallel_1, perp_1) is True assert Line3D.is_perpendicular(parallel_1, parallel_2) is False # Test projection assert parallel_1.projection(Point3D(5, 5, 0)) == Point3D(5, 0, 0) assert parallel_1.projection(parallel_2) == [parallel_1] pytest.raises(GeometryError, lambda: parallel_1.projection(Plane(p1, p2, p6))) # Test __new__ assert Line3D(perp_1) == perp_1 pytest.raises(ValueError, lambda: Line3D(p1)) # Test contains pt2d = Point(1.0, 1.0) assert perp_1.contains(pt2d) is False # Test equals assert perp_1.equals(pt2d) is False col1 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)) col2 = Line3D(Point3D(-5, 0, 0), Point3D(-1, 0, 0)) assert col1.equals(col2) is True assert col1.equals(perp_1) is False # Begin ray # Test __new__ assert Ray3D(col1) == Ray3D(p1, Point3D(1, 0, 0)) pytest.raises(ValueError, lambda: Ray3D(pt2d)) # Test zdirection negz = Ray3D(p1, Point3D(0, 0, -1)) assert negz.zdirection == -oo # Test contains assert negz.contains(Segment3D(p1, Point3D(0, 0, -10))) is True assert negz.contains(Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))) is False posy = Ray3D(p1, Point3D(0, 1, 0)) posz = Ray3D(p1, Point3D(0, 0, 1)) assert posy.contains(p1) is True assert posz.contains(p1) is True assert posz.contains(pt2d) is False ray1 = Ray3D(Point3D(1, 1, 1), Point3D(1, 0, 0)) pytest.raises(TypeError, lambda: ray1.contains([])) # Test equals assert negz.equals(pt2d) is False assert negz.equals(negz) is True assert ray1.is_similar(Line3D(Point3D(1, 1, 1), Point3D(1, 0, 0))) is True assert ray1.is_similar(perp_1) is False pytest.raises(NotImplementedError, lambda: ray1.is_similar(ray1)) # Begin Segment seg1 = Segment3D(p1, Point3D(1, 0, 0)) pytest.raises(TypeError, lambda: seg1.contains([])) seg2 = Segment3D(Point3D(2, 2, 2), Point3D(3, 2, 2)) assert seg1.contains(seg2) is False
def test_ellipse_geom(): 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) pytest.raises(ValueError, lambda: Ellipse(Point3D(0, 0, 0), 1, 1)) pytest.raises(ValueError, lambda: e3.arbitrary_point(y1)) assert e1.ambient_dimension == 2 # 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) pytest.raises(GeometryError, lambda: Circle(Point(0, 0), Point(1, 1), Point(2, 2))) pytest.raises(ValueError, lambda: Ellipse(None, None, None, 1)) pytest.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 # issue sympy/sympy#12303 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 # 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 False 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))), ] 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 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)) ] # test the failure of Poly.intervals and checks a point on the boundary p = Point(sqrt(3), Rational(1, 2)) assert p in e assert 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)) ] # be sure to use the slope that isn't undefined on boundary e = Ellipse((0, 0), 2, 2 * sqrt(3) / 3) assert e.normal_lines((1, 1), 2) == [ Line(Point(-64 / 33, -20 / 71), Point(-31 / 33, 2 / 13)), Line(Point(1, -1), Point(2, -4)) ] # 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))] pytest.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) # 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 # 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) pytest.raises(NotImplementedError, lambda: e.rotate(pi / 3)) # Circle rotation tests (issue sympy/sympy#11743) cir = Circle(Point(1, 0), 1) assert cir.rotate(pi / 2) == Circle(Point(0, 1), 1) assert cir.rotate(pi / 3) == Circle(Point(Rational(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(Rational(1, 2) + sqrt(3) / 2, Rational(1, 2) + sqrt(3) / 2), 1) # transformations c = Circle((1, 1), 2) assert c.scale(-1) == Circle((-1, 1), 2) assert c.scale(y=-1) == Circle((1, -1), 2) assert c.scale(2) == Ellipse((2, 1), 4, 2) e1 = Ellipse(Point(1, 0), 3, 2) assert (e1.evolute() == root(4, 3) * y**Rational(2, 3) + (3 * x - 3)**Rational(2, 3) - root(25, 3)) e1 = Ellipse(Point(0, 0), 3, 2) p1 = e1.random_point(seed=0) assert p1.evalf(2) == Point(2.0664, 1.4492) assert Ellipse((1, 0), 2, 1).rotate(pi / 2) == Ellipse(Point(0, 1), 1, 2)
def test_plane2(): p1 = Plane(Point3D(0, 0, 0), normal_vector=(1, 0, 0)) p2 = Plane(Point3D(0, 0, 0), normal_vector=(1, 0, -1)) assert p1.intersection(p2) == [Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))] p1 = Plane(Point3D(0, 0, 1), normal_vector=(0, -5, 3)) p2 = Plane(Point3D(0, 0, 2), normal_vector=(0, -5, -3)) assert p1.intersection(p2) == [ Line3D(Point3D(0, 3 / 10, 3 / 2), Point3D(30, 3 / 10, 3 / 2)) ] p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(1, 2, 3) pl3 = Plane(p1, p2, p3) # get a segment that does not intersect the plane which is also # parallel to pl3's normal veector t = Dummy() r = pl3.random_point() a = pl3.perpendicular_line(r).arbitrary_point(t) s = Segment3D(a.subs(t, 1), a.subs(t, 2)) assert s.p1 not in pl3 and s.p2 not in pl3
def test_plane2(): p1 = Plane(Point3D(0, 0, 0), normal_vector=(1, 0, 0)) p2 = Plane(Point3D(0, 0, 0), normal_vector=(1, 0, -1)) assert p1.intersection(p2) == [Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))] p1 = Plane(Point3D(0, 0, 1), normal_vector=(0, -5, 3)) p2 = Plane(Point3D(0, 0, 2), normal_vector=(0, -5, -3)) assert p1.intersection(p2) == [ Line3D(Point3D(0, 3 / 10, 3 / 2), Point3D(30, 3 / 10, 3 / 2)) ] p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(1, 2, 3) pl3 = Plane(p1, p2, p3) # get a segment that does not intersect the plane which is also # parallel to pl3's normal veector t = Dummy() r = pl3.random_point() a = pl3.perpendicular_line(r).arbitrary_point(t) s = Segment3D(a.subs({t: 1}), a.subs({t: 2})) assert s.p1 not in pl3 and s.p2 not in pl3 a = Plane(Point3D(5, 0, 0), normal_vector=(1, -1, 1)) b = Plane(Point3D(0, -2, 0), normal_vector=(3, 1, 1)) c = Plane(Point3D(0, -1, 0), normal_vector=(5, -1, 9)) assert Plane.are_concurrent(a, b) is True assert Plane.are_concurrent(a, b, c) is False p = Plane((0, 0, 0), (0, 0, 1), (0, 1, 0)) assert p.arbitrary_point(t) == Point3D(0, cos(t), sin(t))