Beispiel #1
0
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)]
Beispiel #2
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))
Beispiel #3
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))
Beispiel #4
0
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))
Beispiel #5
0
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)
Beispiel #6
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)]'
Beispiel #7
0
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_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",
        ),
    )
Beispiel #9
0
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