def test_projection(): p1 = Point(0, 0) p2 = Point3D(0, 0, 0) p3 = Point(-x1, x1) l1 = Line(p1, Point(1, 1)) l2 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)) l3 = Line3D(p2, Point3D(1, 1, 1)) r1 = Ray(Point(1, 1), Point(2, 2)) assert Line(Point(x1, x1), Point(y1, y1)).projection(Point(y1, y1)) == Point(y1, y1) assert Line(Point(x1, x1), Point(x1, 1 + x1)).projection(Point(1, 1)) == Point(x1, 1) assert Segment(Point(0, 4), Point(-2, 2)).projection(r1) == Segment(Point(0, 4), Point(-1, 3)) assert Segment(Point(0, 4), Point(-2, 2)).projection(r1) == Segment(Point(0, 4), Point(-1, 3)) assert l1.projection(p3) == p1 assert l1.projection(Ray(p1, Point(-1, 5))) == Ray(Point(0, 0), Point(2, 2)) assert l1.projection(Ray(p1, Point(-1, 1))) == p1 assert r1.projection(Ray(Point(1, 1), Point(-1, -1))) == Point(1, 1) assert r1.projection(Ray(Point(0, 4), Point(-1, -5))) == Segment(Point(1, 1), Point(2, 2)) assert r1.projection(Segment(Point(-1, 5), Point(-5, -10))) == Segment(Point(1, 1), Point(2, 2)) assert r1.projection(Ray(Point(1, 1), Point(-1, -1))) == Point(1, 1) assert r1.projection(Ray(Point(0, 4), Point(-1, -5))) == Segment(Point(1, 1), Point(2, 2)) assert r1.projection(Segment(Point(-1, 5), Point(-5, -10))) == Segment(Point(1, 1), Point(2, 2)) assert l3.projection(Ray3D(p2, Point3D(-1, 5, 0))) == Ray3D(Point3D(0, 0, 0), Point3D(4 / 3, 4 / 3, 4 / 3)) assert l3.projection(Ray3D(p2, Point3D(-1, 1, 1))) == Ray3D(Point3D(0, 0, 0), Point3D(1 / 3, 1 / 3, 1 / 3)) assert l2.projection(Point3D(5, 5, 0)) == Point3D(5, 0) assert l2.projection(Line3D(Point3D(0, 1, 0), Point3D(1, 1, 0))).equals(l2)
def test_equals(): p1 = Point(0, 0) p2 = Point(1, 1) l1 = Line(p1, p2) l2 = Line((0, 5), slope=m) l3 = Line(Point(x1, x1), Point(x1, 1 + x1)) assert l1.perpendicular_line(p1.args).equals( Line(Point(0, 0), Point(1, -1))) assert l1.perpendicular_line(p1).equals(Line(Point(0, 0), Point(1, -1))) assert (Line(Point(x1, x1), Point(y1, y1)).parallel_line(Point(-x1, x1)).equals( Line(Point(-x1, x1), Point(-y1, 2 * x1 - y1)))) assert l3.parallel_line(p1.args).equals(Line(Point(0, 0), Point(0, -1))) assert l3.parallel_line(p1).equals(Line(Point(0, 0), Point(0, -1))) assert (l2.distance(Point(2, 3)) - 2 * abs(m + 1) / sqrt(m**2 + 1)).equals(0) assert Line3D(p1, Point3D(0, 1, 0)).equals(Point(1.0, 1.0)) is False assert (Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).equals( Line3D(Point3D(-5, 0, 0), Point3D(-1, 0, 0))) is True) assert (Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).equals( Line3D(p1, Point3D(0, 1, 0))) is False) assert Ray3D(p1, Point3D(0, 0, -1)).equals(Point(1.0, 1.0)) is False assert Ray3D(p1, Point3D(0, 0, -1)).equals(Ray3D(p1, Point3D(0, 0, -1))) is True assert (Line3D((0, 0), (t, t)).perpendicular_line(Point(0, 1, 0)).equals( Line3D(Point3D(0, 1, 0), Point3D(S.Half, S.Half, 0)))) assert (Line3D((0, 0), (t, t)).perpendicular_segment(Point(0, 1, 0)).equals( Segment3D((0, 1), (S.Half, S.Half)))) assert Line3D(p1, Point3D(0, 1, 0)).equals(Point(1.0, 1.0)) is False
def test_basic_properties_3d(): p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(x1, x1, x1) p5 = Point3D(x1, 1 + x1, 1) l1 = Line3D(p1, p2) l3 = Line3D(p3, p5) r1 = Ray3D(p1, Point3D(-1, 5, 0)) r3 = Ray3D(p1, p2) s1 = Segment3D(p1, p2) 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)) assert Line3D(Line3D(p1, Point3D(0, 1, 0))) == Line3D(p1, Point3D(0, 1, 0)) assert Ray3D(Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))) == Ray3D(p1, Point3D(1, 0, 0)) assert Line3D(p1, p2) != Line3D(p2, p1) assert l1 != l3 assert l1 != Line3D(p3, Point3D(y1, y1, y1)) assert r3 != r1 assert Ray3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) in Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)) assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)) in Ray3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) assert p1 in l1 assert p1 not in l3 assert l1.direction_ratio == [1, 1, 1] assert s1.midpoint == Point3D(Rational(1, 2), Rational(1, 2), Rational(1, 2)) # Test zdirection assert Ray3D(p1, Point3D(0, 0, -1)).zdirection == S.NegativeInfinity
def test_intersection_3d(): p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) l1 = Line3D(p1, p2) l2 = Line3D(Point3D(0, 0, 0), Point3D(3, 4, 0)) r1 = Ray3D(Point3D(1, 1, 1), Point3D(2, 2, 2)) r2 = Ray3D(Point3D(0, 0, 0), Point3D(3, 4, 0)) s1 = Segment3D(Point3D(0, 0, 0), Point3D(3, 4, 0)) assert intersection(l1, p1) == [p1] assert intersection(l1, Point3D(x1, 1 + x1, 1)) == [] assert intersection(l1, l1.parallel_line(p1)) == [Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1))] assert intersection(l2, r2) == [r2] assert intersection(l2, s1) == [s1] assert intersection(r2, l2) == [r2] assert intersection(r1, Ray3D(Point3D(1, 1, 1), Point3D(-1, -1, -1))) == [Point3D(1, 1, 1)] assert intersection(r1, Segment3D(Point3D(0, 0, 0), Point3D(2, 2, 2))) == [ Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))] assert intersection(Ray3D(Point3D(1, 0, 0), Point3D(-1, 0, 0)), Ray3D(Point3D(0, 1, 0), Point3D(0, -1, 0))) \ == [Point3D(0, 0, 0)] assert intersection(r1, Ray3D(Point3D(2, 2, 2), Point3D(0, 0, 0))) == \ [Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))] assert intersection(s1, r2) == [s1] assert Line3D(Point3D(4, 0, 1), Point3D(0, 4, 1)).intersection(Line3D(Point3D(0, 0, 1), Point3D(4, 4, 1))) == \ [Point3D(2, 2, 1)] assert Line3D((0, 1, 2), (0, 2, 3)).intersection(Line3D((0, 1, 2), (0, 1, 1))) == [Point3D(0, 1, 2)] assert Line3D((0, 0), (t, t)).intersection(Line3D((0, 1), (t, t))) == \ [Point3D(t, t)] assert Ray3D(Point3D(0, 0, 0), Point3D(0, 4, 0)).intersection(Ray3D(Point3D(0, 1, 1), Point3D(0, -1, 1))) == []
def test_contains(): p1 = Point(0, 0) r = Ray(p1, Point(4, 4)) r1 = Ray3D(p1, Point3D(0, 0, -1)) r2 = Ray3D(p1, Point3D(0, 1, 0)) r3 = Ray3D(p1, Point3D(0, 0, 1)) l = Line(Point(0, 1), Point(3, 4)) # Segment contains assert Point(0, (a + b) / 2) in Segment((0, a), (0, b)) assert Point((a + b) / 2, 0) in Segment((a, 0), (b, 0)) assert Point3D(0, 1, 0) in Segment3D((0, 1, 0), (0, 1, 0)) assert Point3D(1, 0, 0) in Segment3D((1, 0, 0), (1, 0, 0)) assert Segment3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).contains([]) is True assert Segment3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).contains( Segment3D(Point3D(2, 2, 2), Point3D(3, 2, 2))) is False # Line contains assert l.contains(Point(0, 1)) is True assert l.contains((0, 1)) is True assert l.contains((0, 0)) is False # Ray contains assert r.contains(p1) is True assert r.contains((1, 1)) is True assert r.contains((1, 3)) is False assert r.contains(Segment((1, 1), (2, 2))) is True assert r.contains(Segment((1, 2), (2, 5))) is False assert r.contains(Ray((2, 2), (3, 3))) is True assert r.contains(Ray((2, 2), (3, 5))) is False assert r1.contains(Segment3D(p1, Point3D(0, 0, -10))) is True assert r1.contains(Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))) is False assert r2.contains(Point3D(0, 0, 0)) is True assert r3.contains(Point3D(0, 0, 0)) is True assert Ray3D(Point3D(1, 1, 1), Point3D(1, 0, 0)).contains([]) is False assert Line3D((0, 0, 0), (x, y, z)).contains((2 * x, 2 * y, 2 * z)) with warnings.catch_warnings(record=True) as w: assert Line3D(p1, Point3D(0, 1, 0)).contains(Point(1.0, 1.0)) is False assert len(w) == 1 with warnings.catch_warnings(record=True) as w: assert r3.contains(Point(1.0, 1.0)) is False assert len(w) == 1
def test_ray_generation(): assert Ray((1, 1), angle=pi / 4) == Ray((1, 1), (2, 2)) assert Ray((1, 1), angle=pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=-pi / 2) == Ray((1, 1), (1, 0)) assert Ray((1, 1), angle=-3 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=5.0 * pi / 2) == Ray((1, 1), (1, 2)) assert Ray((1, 1), angle=pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=3.0 * pi) == Ray((1, 1), (0, 1)) assert Ray((1, 1), angle=4.0 * pi) == Ray((1, 1), (2, 1)) assert Ray((1, 1), angle=0) == Ray((1, 1), (2, 1)) assert Ray((1, 1), angle=4.05 * pi) == Ray( Point(1, 1), Point( 2, -sqrt(5) * sqrt(2 * sqrt(5) + 10) / 4 - sqrt(2 * sqrt(5) + 10) / 4 + 2 + sqrt(5), ), ) assert Ray((1, 1), angle=4.02 * pi) == Ray(Point(1, 1), Point(2, 1 + tan(4.02 * pi))) assert Ray((1, 1), angle=5) == Ray((1, 1), (2, 1 + tan(5))) 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))
def test_is_similar(): p1 = Point(2000, 2000) p2 = p1.scale(2, 2) r1 = Ray3D(Point3D(1, 1, 1), Point3D(1, 0, 0)) r2 = Ray(Point(0, 0), Point(0, 1)) s1 = Segment(Point(0, 0), p1) assert s1.is_similar(Segment(p1, p2)) assert s1.is_similar(r2) is False assert r1.is_similar(Line3D(Point3D(1, 1, 1), Point3D(1, 0, 0))) is True assert r1.is_similar(Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))) is False
def test_distance_3d(): p1, p2 = Point3D(0, 0, 0), Point3D(1, 1, 1) p3 = Point3D(Rational(3) / 2, Rational(3) / 2, Rational(3) / 2) s1 = Segment3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) s2 = Segment3D(Point3D(S.Half, S.Half, S.Half), Point3D(1, 0, 1)) r = Ray3D(p1, p2) assert s1.distance(p1) == 0 assert s2.distance(p1) == sqrt(3) / 2 assert s2.distance(p3) == 2 * sqrt(6) / 3 assert s1.distance((0, 0, 0)) == 0 assert s2.distance((0, 0, 0)) == sqrt(3) / 2 assert s1.distance(p1) == 0 assert s2.distance(p1) == sqrt(3) / 2 assert s2.distance(p3) == 2 * sqrt(6) / 3 assert s1.distance((0, 0, 0)) == 0 assert s2.distance((0, 0, 0)) == sqrt(3) / 2 # Line to point assert Line3D(p1, p2).distance(Point3D(-1, 1, 1)) == 2 * sqrt(6) / 3 assert Line3D(p1, p2).distance(Point3D(1, -1, 1)) == 2 * sqrt(6) / 3 assert Line3D(p1, p2).distance(Point3D(2, 2, 2)) == 0 assert Line3D(p1, p2).distance((2, 2, 2)) == 0 assert Line3D(p1, p2).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 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
def test_raises(): d, e = symbols('a,b', real=True) s = Segment((d, 0), (e, 0)) raises(TypeError, lambda: Line((1, 1), 1)) raises(ValueError, lambda: Line(Point(0, 0), Point(0, 0))) raises(Undecidable, lambda: Point(2 * d, 0) in s) raises(ValueError, lambda: Ray3D(Point(1.0, 1.0))) raises(ValueError, lambda: Line3D(Point3D(0, 0, 0), Point3D(0, 0, 0))) raises(TypeError, lambda: Line3D((1, 1), 1)) raises(ValueError, lambda: Line3D(Point3D(0, 0, 0))) raises(TypeError, lambda: Ray((1, 1), 1)) raises(GeometryError, lambda: Line(Point(0, 0), Point(1, 0)) .projection(Circle(Point(0, 0), 1)))
def test_arbitrary_point(): l1 = Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) l2 = Line(Point(x1, x1), Point(y1, y1)) assert l2.arbitrary_point() in l2 assert Ray((1, 1), angle=pi / 4).arbitrary_point() == \ Point(t + 1, t + 1) assert Segment((1, 1), (2, 3)).arbitrary_point() == Point(1 + t, 1 + 2 * t) assert l1.perpendicular_segment(l1.arbitrary_point()) == l1.arbitrary_point() assert Ray3D((1, 1, 1), direction_ratio=[1, 2, 3]).arbitrary_point() == \ Point3D(t + 1, 2 * t + 1, 3 * t + 1) assert Segment3D(Point3D(0, 0, 0), Point3D(1, 1, 1)).midpoint == \ Point3D(Rational(1, 2), Rational(1, 2), Rational(1, 2)) assert Segment3D(Point3D(x1, x1, x1), Point3D(y1, y1, y1)).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)
def test_geometry(): def do_test(*g, s=GeometrySeries, **kwargs): s1 = _build_series(*g, pt="g", **kwargs) assert isinstance(s1, s) # since the range could be None, it is imperative to test that label # receive the correct value. assert s1.label == str(g[0]) s2 = _build_series(*g, **kwargs) assert isinstance(s2, s) assert s2.label == str(g[0]) assert np.array_equal(s1.get_data(), s2.get_data(), equal_nan=True) x, y, z = symbols("x, y, z") do_test(Point2D(1, 2)) do_test(Point3D(1, 2, 3)) do_test(Ray((1, 2), (3, 4))) do_test(Segment((1, 2), (3, 4))) do_test(Line((1, 2), (3, 4)), (x, -5, 5)) do_test(Ray3D((1, 2, 3), (3, 4, 5))) do_test(Segment3D((1, 2, 3), (3, 4, 5))) do_test(Line3D((1, 2, 3), (3, 4, 5))) do_test(Polygon((1, 2), 3, n=10)) do_test(Circle((1, 2), 3)) do_test(Ellipse((1, 2), hradius=3, vradius=2)) do_test(Plane((0, 0, 0), (1, 1, 1)), (x, -5, 5), (y, -4, 4), (z, -3, 3), s=PlaneSeries) # Interactive series. Note that GeometryInteractiveSeries is an instance of # GeometrySeries do_test(Point2D(x, y), params={x: 1, y: 2}) do_test( Plane((x, y, z), (1, 1, 1)), (x, -5, 5), (y, -4, 4), (z, -3, 3), params={ x: 1, y: 2, z: 3 }, s=PlaneInteractiveSeries, )
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_intersection_2d(): p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(x1, x1) p4 = Point(y1, y1) l1 = Line(p1, p2) l3 = Line(Point(0, 0), Point(3, 4)) r1 = Ray(Point(1, 1), Point(2, 2)) r2 = Ray(Point(0, 0), Point(3, 4)) r4 = Ray(p1, p2) r6 = Ray(Point(0, 1), Point(1, 2)) r7 = Ray(Point(0.5, 0.5), Point(1, 1)) s1 = Segment(p1, p2) s2 = Segment(Point(0.25, 0.25), Point(0.5, 0.5)) s3 = Segment(Point(0, 0), Point(3, 4)) assert intersection(l1, p1) == [p1] assert intersection(l1, Point(x1, 1 + x1)) == [] assert intersection(l1, Line(p3, p4)) in [[l1], [Line(p3, p4)]] assert intersection(l1, l1.parallel_line(Point(x1, 1 + x1))) == [] assert intersection(l3, l3) == [l3] assert intersection(l3, r2) == [r2] assert intersection(l3, s3) == [s3] assert intersection(s3, l3) == [s3] assert (intersection(Segment(Point(-10, 10), Point(10, 10)), Segment(Point(-5, -5), Point(-5, 5))) == []) assert intersection(r2, l3) == [r2] assert intersection(r1, Ray(Point(2, 2), Point(0, 0))) == [Segment(Point(1, 1), Point(2, 2))] assert intersection(r1, Ray(Point(1, 1), Point(-1, -1))) == [Point(1, 1)] assert intersection(r1, Segment(Point(0, 0), Point( 2, 2))) == [Segment(Point(1, 1), Point(2, 2))] assert r4.intersection(s2) == [s2] assert r4.intersection(Segment(Point(2, 3), Point(3, 4))) == [] assert r4.intersection(Segment(Point(-1, -1), Point( 0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] assert r4.intersection(Ray(p2, p1)) == [s1] assert Ray(p2, p1).intersection(r6) == [] assert r4.intersection(r7) == r7.intersection(r4) == [r7] assert Ray3D((0, 0), (3, 0)).intersection(Ray3D( (1, 0), (3, 0))) == [Ray3D((1, 0), (3, 0))] assert Ray3D((1, 0), (3, 0)).intersection(Ray3D( (0, 0), (3, 0))) == [Ray3D((1, 0), (3, 0))] assert Ray(Point(0, 0), Point(0, 4)).intersection( Ray(Point(0, 1), Point(0, -1))) == [Segment(Point(0, 0), Point(0, 1))] 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((2, 0), (3, 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)] assert s1.intersection(Segment(Point(1, 1), Point(2, 2))) == [Point(1, 1)] assert s1.intersection(Segment(Point(0.5, 0.5), Point( 1.5, 1.5))) == [Segment(Point(0.5, 0.5), p2)] assert s1.intersection(Segment(Point(4, 4), Point(5, 5))) == [] assert s1.intersection(Segment(Point(-1, -1), p1)) == [p1] assert s1.intersection(Segment(Point(-1, -1), Point( 0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] assert s1.intersection(Line(Point(1, 0), Point(2, 1))) == [] assert s1.intersection(s2) == [s2] assert s2.intersection(s1) == [s2] assert asa(120, 8, 52) == Triangle( Point(0, 0), Point(8, 0), Point( -4 * cos(19 * pi / 90) / sin(2 * pi / 45), 4 * sqrt(3) * cos(19 * pi / 90) / sin(2 * pi / 45), ), ) assert Line((0, 0), (1, 1)).intersection(Ray((1, 0), (1, 2))) == [Point(1, 1)] assert Line((0, 0), (1, 1)).intersection(Segment((1, 0), (1, 2))) == [Point(1, 1)] assert Ray((0, 0), (1, 1)).intersection(Ray((1, 0), (1, 2))) == [Point(1, 1)] assert Ray((0, 0), (1, 1)).intersection(Segment((1, 0), (1, 2))) == [Point(1, 1)] assert Ray((0, 0), (10, 10)).contains(Segment((1, 1), (2, 2))) is True assert Segment((1, 1), (2, 2)) in Line((0, 0), (10, 10)) assert s1.intersection(Ray((1, 1), (4, 4))) == [Point(1, 1)]
def test_intersection_2d(): p1 = Point(0, 0) p2 = Point(1, 1) p3 = Point(x1, x1) p4 = Point(y1, y1) l1 = Line(p1, p2) l3 = Line(Point(0, 0), Point(3, 4)) r1 = Ray(Point(1, 1), Point(2, 2)) r2 = Ray(Point(0, 0), Point(3, 4)) r4 = Ray(p1, p2) r6 = Ray(Point(0, 1), Point(1, 2)) r7 = Ray(Point(0.5, 0.5), Point(1, 1)) s1 = Segment(p1, p2) s2 = Segment(Point(0.25, 0.25), Point(0.5, 0.5)) s3 = Segment(Point(0, 0), Point(3, 4)) assert intersection(l1, p1) == [p1] assert intersection(l1, Point(x1, 1 + x1)) == [] assert intersection(l1, Line(p3, p4)) in [[l1], [Line(p3, p4)]] assert intersection(l1, l1.parallel_line(Point(x1, 1 + x1))) == [] assert intersection(l3, l3) == [l3] assert intersection(l3, r2) == [r2] assert intersection(l3, s3) == [s3] assert intersection(s3, l3) == [s3] assert intersection(Segment(Point(-10, 10), Point(10, 10)), Segment(Point(-5, -5), Point(-5, 5))) == [] assert intersection(r2, l3) == [r2] assert intersection(r1, Ray(Point(2, 2), Point(0, 0))) == [Segment(Point(1, 1), Point(2, 2))] assert intersection(r1, Ray(Point(1, 1), Point(-1, -1))) == [Point(1, 1)] assert intersection(r1, Segment(Point(0, 0), Point(2, 2))) == [Segment(Point(1, 1), Point(2, 2))] assert r4.intersection(s2) == [s2] assert r4.intersection(Segment(Point(2, 3), Point(3, 4))) == [] assert r4.intersection(Segment(Point(-1, -1), Point(0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] assert r4.intersection(Ray(p2, p1)) == [s1] assert Ray(p2, p1).intersection(r6) == [] assert r4.intersection(r7) == r7.intersection(r4) == [r7] assert Ray3D((0, 0), (3, 0)).intersection(Ray3D((1, 0), (3, 0))) == [Ray3D((1, 0), (3, 0))] assert Ray3D((1, 0), (3, 0)).intersection(Ray3D((0, 0), (3, 0))) == [Ray3D((1, 0), (3, 0))] assert Ray(Point(0, 0), Point(0, 4)).intersection(Ray(Point(0, 1), Point(0, -1))) == \ [Segment(Point(0, 0), Point(0, 1))] 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((2, 0), (3, 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)] assert s1.intersection(Segment(Point(1, 1), Point(2, 2))) == [Point(1, 1)] assert s1.intersection(Segment(Point(0.5, 0.5), Point(1.5, 1.5))) == [Segment(Point(0.5, 0.5), p2)] assert s1.intersection(Segment(Point(4, 4), Point(5, 5))) == [] assert s1.intersection(Segment(Point(-1, -1), p1)) == [p1] assert s1.intersection(Segment(Point(-1, -1), Point(0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))] assert s1.intersection(Line(Point(1, 0), Point(2, 1))) == [] assert s1.intersection(s2) == [s2] assert s2.intersection(s1) == [s2] assert asa(120, 8, 52) == \ Triangle( Point(0, 0), Point(8, 0), Point(-4 * cos(19 * pi / 90) / sin(2 * pi / 45), 4 * sqrt(3) * cos(19 * pi / 90) / sin(2 * pi / 45))) assert Line((0, 0), (1, 1)).intersection(Ray((1, 0), (1, 2))) == [Point(1, 1)] assert Line((0, 0), (1, 1)).intersection(Segment((1, 0), (1, 2))) == [Point(1, 1)] assert Ray((0, 0), (1, 1)).intersection(Ray((1, 0), (1, 2))) == [Point(1, 1)] assert Ray((0, 0), (1, 1)).intersection(Segment((1, 0), (1, 2))) == [Point(1, 1)] assert Ray((0, 0), (10, 10)).contains(Segment((1, 1), (2, 2))) is True assert Segment((1, 1), (2, 2)) in Line((0, 0), (10, 10)) assert s1.intersection(Ray((1, 1), (4, 4))) == [Point(1, 1)] # 16628 - this should be fast p0 = Point2D(Rational(249, 5), Rational(497999, 10000)) p1 = Point2D((-58977084786*sqrt(405639795226) + 2030690077184193 + 20112207807*sqrt(630547164901) + 99600*sqrt(255775022850776494562626)) /(2000*sqrt(255775022850776494562626) + 1991998000*sqrt(405639795226) + 1991998000*sqrt(630547164901) + 1622561172902000), (-498000*sqrt(255775022850776494562626) - 995999*sqrt(630547164901) + 90004251917891999 + 496005510002*sqrt(405639795226))/(10000*sqrt(255775022850776494562626) + 9959990000*sqrt(405639795226) + 9959990000*sqrt(630547164901) + 8112805864510000)) p2 = Point2D(Rational(497, 10), Rational(-497, 10)) p3 = Point2D(Rational(-497, 10), Rational(-497, 10)) l = Line(p0, p1) s = Segment(p2, p3) n = (-52673223862*sqrt(405639795226) - 15764156209307469 - 9803028531*sqrt(630547164901) + 33200*sqrt(255775022850776494562626)) d = sqrt(405639795226) + 315274080450 + 498000*sqrt( 630547164901) + sqrt(255775022850776494562626) assert intersection(l, s) == [ Point2D(n/d*Rational(3, 2000), Rational(-497, 10))]
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