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))
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_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_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_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