def test_dimension_normalization(): A = Plane(Point3D(1, 1, 2), normal_vector=(1, 1, 1)) b = Point(1, 1) assert A.projection(b) == Point(S(5)/3, S(5)/3, S(2)/3) a, b = Point(0, 0), Point3D(0, 1) Z = (0, 0, 1) p = Plane(a, normal_vector=Z) assert p.perpendicular_plane(a, b) == Plane(Point3D(0, 0, 0), (1, 0, 0)) assert Plane((1, 2, 1), (2, 1, 0), (3, 1, 2) ).intersection((2, 1)) == [Point(2, 1, 0)]
def test_parameter_value(): t, u, v = symbols("t, u v") p1, p2, p3 = Point(0, 0, 0), Point(0, 0, 1), Point(0, 1, 0) p = Plane(p1, p2, p3) assert p.parameter_value((0, -3, 2), t) == {t: asin(2*sqrt(13)/13)} assert p.parameter_value((0, -3, 2), u, v) == {u: 3, v: 2} assert p.parameter_value(p1, t) == p1 raises(ValueError, lambda: p.parameter_value((1, 0, 0), t)) raises(ValueError, lambda: p.parameter_value(Line(Point(0, 0), Point(1, 1)), t)) raises(ValueError, lambda: p.parameter_value((0, -3, 2), t, 1))
def test_dimension_normalization(): A = Plane(Point3D(1, 1, 2), normal_vector=(1, 1, 1)) b = Point(1, 1) assert A.projection(b) == Point(5/3, 5/3, 2/3) a, b = Point(0, 0), Point3D(0, 1) Z = (0, 0, 1) p = Plane(a, normal_vector=Z) assert p.perpendicular_plane(a, b) == Plane(Point3D(0, 0, 0), (1, 0, 0)) assert Plane((1, 2, 1), (2, 1, 0), (3, 1, 2) ).intersection((2, 1)) == [Point(2, 1, 0)]
def test_geometry_EvalfMixin(): x = pi t = Symbol('t') for g in [ Point(x, x), Plane(Point(0, x, 0), (0, 0, x)), Curve((x * t, x), (t, 0, x)), Ellipse((x, x), x, -x), Circle((x, x), x), Line((0, x), (x, 0)), Segment((0, x), (x, 0)), Ray((0, x), (x, 0)), Parabola((0, x), Line((-x, 0), (x, 0))), Polygon((0, 0), (0, x), (x, 0), (x, x)), RegularPolygon((0, x), x, 4, x), Triangle((0, 0), (x, 0), (x, x)), ]: assert str(g).replace('pi', '3.1') == str(g.n(2))
def test_vector_integrate(): halfdisc = ParametricRegion((r * cos(theta), r * sin(theta)), (r, -2, 2), (theta, 0, pi)) assert vector_integrate(C.x**2, halfdisc) == 4 * pi vector_integrate(C.x, ParametricRegion( (t, t**2), (t, 2, 3))) == -17 * sqrt(17) / 12 + 37 * sqrt(37) / 12 assert vector_integrate(C.y**3 * C.z, (C.x, 0, 3), (C.y, -1, 4)) == 765 * C.z / 4 s1 = Segment(Point(0, 0), Point(0, 1)) assert vector_integrate(-15 * C.y, s1) == S(-15) / 2 s2 = Segment(Point(4, 3, 9), Point(1, 1, 7)) assert vector_integrate(C.y * C.i, s2) == -6 curve = Curve((sin(t), cos(t)), (t, 0, 2)) assert vector_integrate(5 * C.z, curve) == 10 * C.z c1 = Circle(Point(2, 3), 6) assert vector_integrate(C.x * C.y, c1) == 72 * pi c2 = Circle(Point(0, 0), Point(1, 1), Point(1, 0)) assert vector_integrate(1, c2) == c2.circumference triangle = Polygon((0, 0), (1, 0), (1, 1)) assert vector_integrate(C.x * C.i - 14 * C.y * C.j, triangle) == 0 p1, p2, p3, p4 = [(0, 0), (1, 0), (5, 1), (0, 1)] poly = Polygon(p1, p2, p3, p4) assert vector_integrate(-23 * C.z, poly) == -161 * C.z - 23 * sqrt(17) * C.z point = Point(2, 3) assert vector_integrate(C.i * C.y - C.z, point) == ParametricIntegral( C.y * C.i, ParametricRegion((2, 3))) c3 = ImplicitRegion((x, y), x**2 + y**2 - 4) assert vector_integrate(45, c3) == 360 * pi c4 = ImplicitRegion((x, y), (x - 3)**2 + (y - 4)**2 - 9) assert vector_integrate(1, c4) == 12 * pi pl = Plane(Point(1, 1, 1), Point(2, 3, 4), Point(2, 2, 2)) raises(ValueError, lambda: vector_integrate(C.x * C.z * C.i + C.k, pl))
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): 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): assert p - p_4d == Point(1, 1, 1, -1) p_4d3d = Point(0, 0, 1, 0) with warns(UserWarning): assert p - p_4d3d == Point(1, 1, 0, 0)
def test_plane(): x, y, z, u, v = symbols('x y z u v', real=True) p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(1, 2, 3) 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)) pl8 = Plane(p1, normal_vector=(0, 0, 1)) pl9 = Plane(p1, normal_vector=(0, 12, 0)) pl10 = Plane(p1, normal_vector=(-2, 0, 0)) pl11 = Plane(p2, normal_vector=(0, 0, 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 pl6.distance(pl6.arbitrary_point(u, v)) == 0 assert pl7.distance(pl7.arbitrary_point(u, v)) == 0 assert pl6.distance(pl6.arbitrary_point(t)) == 0 assert pl7.distance(pl7.arbitrary_point(t)) == 0 assert pl6.p1.distance(pl6.arbitrary_point(t)).simplify() == 1 assert pl7.p1.distance(pl7.arbitrary_point(t)).simplify() == 1 assert pl3.arbitrary_point(t) == Point3D(-sqrt(30)*sin(t)/30 + \ 2*sqrt(5)*cos(t)/5, sqrt(30)*sin(t)/15 + sqrt(5)*cos(t)/5, sqrt(30)*sin(t)/6) assert pl3.arbitrary_point(u, v) == Point3D(2*u - v, u + 2*v, 5*v) 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 raises(ValueError, lambda: Plane.are_concurrent(Point3D(0, 0, 0))) raises(ValueError, lambda: Plane((1, 2, 3), normal_vector=(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 pl9.intersection(pl8) == [Line3D(Point3D(0, 0, 0), Point3D(12, 0, 0))] assert pl10.intersection(pl11) == [Line3D(Point3D(0, 0, 1), Point3D(0, 2, 1))] assert pl4.intersection(pl8) == [Line3D(Point3D(0, 0, 0), Point3D(1, -1, 0))] assert pl11.intersection(pl8) == [] assert pl9.intersection(pl11) == [Line3D(Point3D(0, 0, 1), Point3D(12, 0, 1))] assert pl9.intersection(pl4) == [Line3D(Point3D(0, 0, 0), Point3D(12, 0, -12))] assert pl3.random_point() in pl3 # test geometrical entity using equals assert pl4.intersection(pl4.p1)[0].equals(pl4.p1) assert pl3.intersection(pl6)[0].equals(Line3D(Point3D(8, 4, 0), Point3D(2, 4, 6))) pl8 = Plane((1, 2, 0), normal_vector=(0, 0, 1)) assert pl8.intersection(Line3D(p1, (1, 12, 0)))[0].equals(Line((0, 0, 0), (0.1, 1.2, 0))) assert pl8.intersection(Ray3D(p1, (1, 12, 0)))[0].equals(Ray((0, 0, 0), (1, 12, 0))) assert pl8.intersection(Segment3D(p1, (21, 1, 0)))[0].equals(Segment3D(p1, (21, 1, 0))) assert pl8.intersection(Plane(p1, normal_vector=(0, 0, 112)))[0].equals(pl8) assert pl8.intersection(Plane(p1, normal_vector=(0, 12, 0)))[0].equals( Line3D(p1, direction_ratio=(112 * pi, 0, 0))) assert pl8.intersection(Plane(p1, normal_vector=(11, 0, 1)))[0].equals( Line3D(p1, direction_ratio=(0, -11, 0))) assert pl8.intersection(Plane(p1, normal_vector=(1, 0, 11)))[0].equals( Line3D(p1, direction_ratio=(0, 11, 0))) assert pl8.intersection(Plane(p1, normal_vector=(-1, -1, -11)))[0].equals( Line3D(p1, direction_ratio=(1, -1, 0))) assert pl3.random_point() in pl3 assert len(pl8.intersection(Ray3D(Point3D(0, 2, 3), Point3D(1, 0, 3)))) is 0 # check if two plane are equals assert pl6.intersection(pl6)[0].equals(pl6) assert pl8.equals(Plane(p1, normal_vector=(0, 12, 0))) is False assert pl8.equals(pl8) assert pl8.equals(Plane(p1, normal_vector=(0, 0, -12))) assert pl8.equals(Plane(p1, normal_vector=(0, 0, -12*sqrt(3)))) # issue 8570 l2 = Line3D(Point3D(S(50000004459633)/5000000000000, -S(891926590718643)/1000000000000000, S(231800966893633)/100000000000000), Point3D(S(50000004459633)/50000000000000, -S(222981647679771)/250000000000000, S(231800966893633)/100000000000000)) p2 = Plane(Point3D(S(402775636372767)/100000000000000, -S(97224357654973)/100000000000000, S(216793600814789)/100000000000000), (-S('9.00000087501922'), -S('4.81170658872543e-13'), S('0.0'))) assert str([i.n(2) for i in p2.intersection(l2)]) == \ '[Point3D(4.0, -0.89, 2.3)]'
def test_parameter_value(): t, u, v = symbols("t, u v") p = Plane((0, 0, 0), (0, 0, 1), (0, 1, 0)) assert p.parameter_value((0, -3, 2), t) == {t: asin(2*sqrt(13)/13)} assert p.parameter_value((0, -3, 2), u, v) == {u: 3, v: 2} raises(ValueError, lambda: p.parameter_value((1, 0, 0), t))
def test_parameter_value(): t, u, v = symbols("t, u v") p = Plane((0, 0, 0), (0, 0, 1), (0, 1, 0)) assert p.parameter_value((0, -3, 2), t) == {t: asin(2 * sqrt(13) / 13)} assert p.parameter_value((0, -3, 2), u, v) == {u: 3, v: 2} raises(ValueError, lambda: p.parameter_value((1, 0, 0), t))
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 = Rational(1, 2) 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) 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) 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.n(2), b.n(2)) 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(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 warnings.catch_warnings(record=True) as w: 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 warnings.catch_warnings(record=True) as w: assert p - p_4d == Point(1, 1, 1, -1) assert len(w) == 1 p_4d3d = Point(0, 0, 1, 0) with warnings.catch_warnings(record=True) as w: assert p - p_4d3d == Point(1, 1, 0, 0) assert len(w) == 1
def test_series(): x, y, z = symbols("x:z") N = CoordSys3D("N") v1 = x * N.i + y * N.j v2 = z * N.i + x * N.j + y * N.k m1 = v1.to_matrix(N) m2 = v2.to_matrix(N) # Tests for 2D vectors args = pw(v1, "test")[0] _, _, s = _series(args[0], *args[1:-1], label=args[-1]) assert isinstance(s, Vector2DSeries) # auto generate ranges t1 = (s.u.var_x, s.u.start_x, s.u.end_x) t2 = (s.u.var_y, s.u.start_y, s.u.end_y) assert (t1 == (x, -10.0, 10.0)) or (t1 == (y, -10.0, 10.0)) assert (t2 == (x, -10.0, 10.0)) or (t2 == (y, -10.0, 10.0)) args = pw(v1, (x, -5, 5), "test")[0] _, _, s = _series(args[0], *args[1:-1], label=args[-1]) assert isinstance(s, Vector2DSeries) assert (s.u.var_x, s.u.start_x, s.u.end_x) == (x, -5.0, 5.0) # auto generate range assert (s.u.var_y, s.u.start_y, s.u.end_y) == (y, -10.0, 10.0) # vector doesn't contain free symbols, and not all ranges were provided. # raise error because the missing range could be any symbol. args = pw([1, 2], (x, -5, 5), "test")[0] raises(ValueError, lambda: _series(args[0], *args[1:-1], label=args[-1])) # too many free symbols in the 2D vector args = pw([x + y, z], (x, -5, 5), "test")[0] raises(ValueError, lambda: _series(args[0], *args[1:-1], label=args[-1])) # Tests for 3D vectors args = pw(v2, "test")[0] _, _, s = _series(args[0], *args[1:-1], label=args[-1]) assert isinstance(s, Vector3DSeries) # auto generate ranges t1 = (s.var_x, s.start_x, s.end_x) t2 = (s.var_y, s.start_y, s.end_y) t3 = (s.var_z, s.start_z, s.end_z) assert ( (t1 == (x, -10.0, 10.0)) or (t1 == (y, -10.0, 10.0)) or (t1 == (z, -10.0, 10.0)) ) assert ( (t2 == (x, -10.0, 10.0)) or (t2 == (y, -10.0, 10.0)) or (t2 == (z, -10.0, 10.0)) ) assert ( (t3 == (x, -10.0, 10.0)) or (t3 == (y, -10.0, 10.0)) or (t3 == (z, -10.0, 10.0)) ) args = pw(v2, (x, -5, 5), "test")[0] _, _, s = _series(args[0], *args[1:-1], label=args[-1]) assert isinstance(s, Vector3DSeries) t1 = (s.var_x, s.start_x, s.end_x) t2 = (s.var_y, s.start_y, s.end_y) t3 = (s.var_z, s.start_z, s.end_z) assert t1 == (x, -5.0, 5.0) assert (t2 == (y, -10.0, 10.0)) or (t2 == (z, -10.0, 10.0)) assert (t3 == (y, -10.0, 10.0)) or (t3 == (z, -10.0, 10.0)) # vector doesn't contain free symbols, and not all ranges were provided. # raise error because the missing range could be any symbol. args = pw(Matrix([1, 2, 3]), (x, -5, 5), "test")[0] raises(ValueError, lambda: _series(args[0], *args[1:-1], label=args[-1])) # too many free symbols in the 3D vector a = symbols("a") args = pw(Matrix([x + y, z, a + x]), (x, -5, 5), "test")[0] raises(ValueError, lambda: _series(args[0], *args[1:-1], label=args[-1])) # Test for 3D vector slices # Single slicing plane _, _, s = _series( v2, Tuple(x, -5, 5), Tuple(y, -4, 4), Tuple(z, -3, 3), label="test", slice=Plane((1, 2, 3), (1, 0, 0)), n1=5, n2=6, n3=7, ) assert isinstance(s, (tuple, list)) assert len(s) == 1 assert isinstance(s[0], SliceVector3DSeries) assert s[0].is_slice xx, yy, zz, uu, vv, ww = s[0].get_data() assert all([t.shape == (6, 7) for t in [xx, yy, zz, uu, vv, ww]]) # normal vector of the plane is directed along x-axis. Same value for each # x-coordinate. assert np.all(xx == 1) assert (np.min(yy.flatten()) == -4) and (np.max(yy.flatten()) == 4) assert (np.min(zz.flatten()) == -3) and (np.max(zz.flatten()) == 3) # multiple slicing planes _, _, s = _series( v2, Tuple(x, -5, 5), Tuple(y, -4, 4), Tuple(z, -3, 3), label="test", slice=[ Plane((1, 2, 3), (1, 0, 0)), Plane((1, 2, 3), (0, 1, 0)), Plane((1, 2, 3), (0, 0, 1)), ], n1=5, n2=6, n3=7, ) assert isinstance(s, (tuple, list)) assert len(s) == 3 assert all([isinstance(t, SliceVector3DSeries) for t in s]) xx1, yy1, zz1, uu1, vv1, ww1 = s[0].get_data() xx2, yy2, zz2, uu2, vv2, ww2 = s[1].get_data() xx3, yy3, zz3, uu3, vv3, ww3 = s[2].get_data() assert all([t.shape == (6, 7) for t in [xx1, yy1, zz1, uu1, vv1, ww1]]) assert all([t.shape == (7, 5) for t in [xx2, yy2, zz2, uu2, vv2, ww2]]) assert all([t.shape == (6, 5) for t in [xx3, yy3, zz3, uu3, vv3, ww3]]) assert np.all(xx1 == 1) assert (np.min(yy1.flatten()) == -4) and (np.max(yy1.flatten()) == 4) assert (np.min(zz1.flatten()) == -3) and (np.max(zz1.flatten()) == 3) assert np.all(yy2 == 2) assert (np.min(xx2.flatten()) == -5) and (np.max(xx2.flatten()) == 5) assert (np.min(zz2.flatten()) == -3) and (np.max(zz2.flatten()) == 3) assert np.all(zz3 == 3) assert (np.min(xx3.flatten()) == -5) and (np.max(xx3.flatten()) == 5) assert (np.min(yy3.flatten()) == -4) and (np.max(yy3.flatten()) == 4) # slicing expression (surface) _, _, s = _series( v2, Tuple(x, -5, 5), Tuple(y, -4, 4), Tuple(z, -3, 3), label="test", slice=cos(x ** 2 + y ** 2), n1=5, n2=6, n3=7, ) assert isinstance(s, (tuple, list)) assert len(s) == 1 assert isinstance(s[0], SliceVector3DSeries) assert s[0].is_slice xx, yy, zz, uu, vv, ww = s[0].get_data() assert all([t.shape == (6, 5) for t in [xx, yy, zz, uu, vv, ww]]) # normal vector of the plane is directed along x-axis. Same value for each # x-coordinate. assert (np.min(xx.flatten()) == -5) and (np.max(xx.flatten()) == 5) assert (np.min(yy.flatten()) == -4) and (np.max(yy.flatten()) == 4) # must fail because slice is not an Expr or a Plane or a list of Planes raises( ValueError, lambda: _series( v2, Tuple(x, -5, 5), Tuple(y, -4, 4), Tuple(z, -3, 3), label="test", n1=5, n2=6, n3=7, slice=[-1], ), ) raises( ValueError, lambda: _series( v2, Tuple(x, -5, 5), Tuple(y, -4, 4), Tuple(z, -3, 3), label="test", n1=5, n2=6, n3=7, slice=0, ), ) raises( ValueError, lambda: _series( v2, Tuple(x, -5, 5), Tuple(y, -4, 4), Tuple(z, -3, 3), label="test", n1=5, n2=6, n3=7, slice="test", ), )
def test_line3d(): x = Symbol('x', real=True) y = Symbol('y', real=True) z = Symbol('z', real=True) k = Symbol('k', real=True) x1 = Symbol('x1', real=True) y1 = Symbol('y1', real=True) 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) p7 = Point3D(0, 1, 1) p8 = Point3D(2, 0, 3) p9 = Point3D(2, 1, 4) l1 = Line3D(p1, p2) l2 = Line3D(p3, p4) l3 = Line3D(p3, p5) l4 = Line3D(p1, p6) l5 = Line3D(p1, p7) l6 = Line3D(p8, p9) l7 = Line3D(p2, p9) 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)) 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() assert l1.perpendicular_segment(p) == 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 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))) == [Point3D(0, 1, 2)] 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)] # issue 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) is False assert Line3D.are_concurrent(l1, l1_1, l3) is True 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) == 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) r4 = Ray3D(p2, p1) 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', 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 * sqrt(6) / 3 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((0, 0, 0), (1, 1, 2)).distance((-1, -1, 2)) == 4 * sqrt(3) / 3 assert Ray3D((1, 1, 1), (2, 2, 2)).distance(Point3D(1.5, -3, -1)) == \ Rational(9)/2 assert Ray3D((1, 1, 1), (2, 2, 2)).distance(Point3D(1.5, 3, 1)) == \ sqrt(78)/6 # 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)) r4 = Ray3D(Point3D(0, 4, 2), Point3D(-1, -5, -1)) r5 = Ray3D(Point3D(2, 2, 2), Point3D(3, 3, 3)) 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, 0)).equals( \ Line3D(Point3D(0, 1, 0), Point3D(1/2, 1/2, 0))) assert Line3D((0, 0), (t, t)).perpendicular_segment((0, 1, 0)).equals( \ Segment3D((0, 1), (1/2, 1/2))) assert Line3D((0, 0), (t, t)).intersection(Line3D((0, 1), (t, t))) == \ [Point3D(t, t)] 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) assert parallel_1.projection(parallel_2).equals(parallel_1) raises(GeometryError, lambda: parallel_1.projection(Plane(p1, p2, p6))) # Test __new__ assert Line3D(perp_1) == perp_1 raises(ValueError, lambda: Line3D(p1)) # Test contains pt2d = Point(1.0, 1.0) with warnings.catch_warnings(record=True) as w: assert perp_1.contains(pt2d) is False assert len(w) == 1 # 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)) raises(ValueError, lambda: Ray3D(pt2d)) # Test zdirection negz = Ray3D(p1, Point3D(0, 0, -1)) assert negz.zdirection == S.NegativeInfinity # 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 with warnings.catch_warnings(record=True) as w: assert posz.contains(pt2d) is False assert len(w) == 1 ray1 = Ray3D(Point3D(1, 1, 1), Point3D(1, 0, 0)) assert ray1.contains([]) is False # 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 assert ray1.is_similar(ray1) is True # Begin Segment seg1 = Segment3D(p1, Point3D(1, 0, 0)) assert seg1.contains([]) is True seg2 = Segment3D(Point3D(2, 2, 2), Point3D(3, 2, 2)) assert seg1.contains(seg2) is False