def test_set(): assert sstr(set()) == 'set()' assert sstr(frozenset()) == 'frozenset()' assert sstr({1, 2, 3}) == '{1, 2, 3}' assert sstr(frozenset({1, 2, 3})) == 'frozenset({1, 2, 3})' assert sstr({1, x, x**2, x**3, x**4}) == '{1, x, x**2, x**3, x**4}'
def test_sstrrepr(): assert sstr('abc') == 'abc' assert sstrrepr('abc') == "'abc'" e = ['a', 'b', 'c', x] assert sstr(e) == '[a, b, c, x]' assert sstrrepr(e) == "['a', 'b', 'c', x]"
def test_Dict(): assert str(Dict({1: 1 + x})) == sstr({1: 1 + x}) == '{1: x + 1}' assert str(Dict({ 1: x**2, 2: y * x })) in ('{1: x**2, 2: x*y}', '{2: x*y, 1: x**2}') assert sstr(Dict({1: x**2, 2: y * x})) == '{1: x**2, 2: x*y}'
def test_Differential(): tp = TensorProduct(R2.dx, R2.dy) assert sstr(LieDerivative( R2.e_x, tp)) == 'LieDerivative(e_x, TensorProduct(dx, dy))' g = Function('g') s_field = g(R2.x, R2.y) assert sstr(Differential(s_field)) == 'd(g(x, y))'
def test_sympyissue_8825(): t1, t2 = symbols('t1:3') d = weakref.WeakKeyDictionary([(t1, 1), (t2, 2)]) assert sstr(list(ordered(d.items()))) == '[(t1, 1), (t2, 2)]' del t1 clear_cache() gc.collect() assert sstr(list(ordered(d.items()))) == '[(t2, 2)]'
def test_noncommutative(): A, B, C = symbols('A,B,C', commutative=False) assert sstr(A * B * C**-1) == 'A*B*C**(-1)' assert sstr(C**-1 * A * B) == 'C**(-1)*A*B' assert sstr(A * C**-1 * B) == 'A*C**(-1)*B' assert sstr(sqrt(A)) == 'sqrt(A)' assert sstr(1 / sqrt(A)) == 'A**(-1/2)'
def test_dict(): assert sstr({1: 1 + x}) == '{1: x + 1}' assert str({1: 1 + x}) == "{1: Add(Symbol('x'), Integer(1))}" assert str({ 1: x**2, 2: y * x }) in ( "{1: Pow(Symbol('x'), Integer(2)), 2: Mul(Symbol('x'), Symbol('y'))}", "{1: Mul(Symbol('x'), Symbol('y')), 2: Pow(Symbol('x'), Integer(2))}") assert sstr({1: x**2, 2: y * x}) == '{1: x**2, 2: x*y}'
def test_tuple(): assert sstr((x, )) == '(x,)' assert str((x, )) == "(Symbol('x'),)" assert sstr((x + y, 1 + x)) == '(x + y, x + 1)' assert str( (x + y, 1 + x)) == "(Add(Symbol('x'), Symbol('y')), Add(Symbol('x'), Integer(1)))" assert sstr((x + y, (1 + x, x**2))) == '(x + y, (x + 1, x**2))' assert str( (x + y, (1 + x, x**2)) ) == "(Add(Symbol('x'), Symbol('y')), (Add(Symbol('x'), Integer(1)), Pow(Symbol('x'), Integer(2))))"
def test_list(): assert sstr([x]) == '[x]' assert str([x]) == "[Symbol('x')]" assert sstr([x**2, x * y + 1]) == '[x**2, x*y + 1]' assert str( [x**2, x * y + 1] ) == "[Pow(Symbol('x'), Integer(2)), Add(Mul(Symbol('x'), Symbol('y')), Integer(1))]" assert sstr([x**2, [y + x]]) == '[x**2, [x + y]]' assert str([ x**2, [y + x] ]) == "[Pow(Symbol('x'), Integer(2)), [Add(Symbol('x'), Symbol('y'))]]"
def test_printmethod(): class R(Abs): def _diofantstr(self, printer): return f'foo({printer._print(self.args[0])})' assert sstr(R(x)) == 'foo(x)' class R(Abs): def _diofantstr(self, printer): return 'foo' assert sstr(R(x)) == 'foo'
def test_Matrix_str(): M = Matrix([[x**+1, 1], [y, x + y]]) assert str(M) == 'Matrix([\n[x, 1],\n[y, x + y]])' assert sstr(M) == 'Matrix([\n[x, 1],\n[y, x + y]])' M = Matrix([[1]]) assert str(M) == sstr(M) == 'Matrix([[1]])' M = Matrix([[1, 2]]) assert str(M) == sstr(M) == 'Matrix([[1, 2]])' M = Matrix() assert str(M) == sstr(M) == 'Matrix(0, 0, [])' M = Matrix(0, 1, lambda i, j: 0) assert str(M) == sstr(M) == 'Matrix(0, 1, [])'
def test_catalan(): n = Symbol('n', integer=True) m = Symbol('n', integer=True, positive=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs({n: i}) == c assert catalan(n).rewrite(Product).subs({n: i}).doit() == c assert catalan(x) == catalan(x) assert catalan(2 * x).rewrite(binomial) == binomial(4 * x, 2 * x) / (2 * x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8 / (3 * pi) assert catalan(Rational(1, 2)).rewrite(factorial).rewrite(gamma) ==\ 8 / (3 * pi) assert catalan(3 * x).rewrite(gamma) == 4**( 3 * x) * gamma(3 * x + Rational(1, 2)) / (sqrt(pi) * gamma(3 * x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2, ), 1) assert catalan(n).rewrite(factorial) == factorial( 2 * n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma(0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4)) * catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(Rational(1, 2)).evalf() assert str(c) == '0.848826363156775' c = catalan(I).evalf(3) assert sstr((re(c), im(c))) == '(0.398, -0.0209)'
def test_catalan(): n = Symbol('n', integer=True) m = Symbol('n', integer=True, positive=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs({n: i}) == c assert catalan(n).rewrite(Product).subs({n: i}).doit() == c assert catalan(x) == catalan(x) assert catalan(2*x).rewrite(binomial) == binomial(4*x, 2*x)/(2*x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8/(3*pi) assert catalan(Rational(1, 2)).rewrite(factorial).rewrite(gamma) ==\ 8 / (3 * pi) assert catalan(3*x).rewrite(gamma) == 4**( 3*x)*gamma(3*x + Rational(1, 2))/(sqrt(pi)*gamma(3*x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2,), 1) assert catalan(n).rewrite(factorial) == factorial(2*n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma( 0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4))*catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(Rational(1, 2)).evalf() assert str(c) == '0.848826363156775' c = catalan(I).evalf(3) assert sstr((re(c), im(c))) == '(0.398, -0.0209)'
def test_intcurve_diffequ(): start_point = R2_r.point([1, 0]) vector_field = -R2.y * R2.e_x + R2.x * R2.e_y equations, init_cond = intcurve_diffequ(vector_field, t, start_point) assert sstr( equations ) == '[f_1(t) + Derivative(f_0(t), t), -f_0(t) + Derivative(f_1(t), t)]' assert sstr(init_cond) == '[f_0(0) - 1, f_1(0)]' equations, init_cond = intcurve_diffequ(vector_field, t, start_point, R2_p) assert sstr( equations) == '[Derivative(f_0(t), t), Derivative(f_1(t), t) - 1]' assert sstr(init_cond) == '[f_0(0) - 1, f_1(0)]' start_point = R2_r.point([x, y]) vector_field = R2_r.e_x assert intcurve_series(vector_field, t, start_point, n=3) == Matrix([[t + x], [y]])
def test_posify(): assert sstr( posify(x + Symbol('p', positive=True) + Symbol('n', negative=True))) == '(n + p + _x, {_x: x})' eq, rep = posify(1 / x) assert log(eq).expand().subs(rep) == -log(x) assert sstr(posify([x, 1 + x])) == '([_x, _x + 1], {_x: x})' p = symbols('p', positive=True) n = symbols('n', negative=True) orig = [x, n, p] modified, reps = posify(orig) assert sstr(modified) == '[_x, n, p]' assert [w.subs(reps) for w in modified] == orig assert sstr(Integral(posify(1/x + y)[0], (y, 1, 3)).expand()) == \ 'Integral(1/_x, (y, 1, 3)) + Integral(_y, (y, 1, 3))' assert sstr(Sum(posify(1/x**n)[0], (n, 1, 3)).expand()) == \ 'Sum(_x**(-n), (n, 1, 3))'
def test_full_prec(): assert sstr(Float(0.3), full_prec=True) == '0.300000000000000' assert sstr(Float(0.3), full_prec='auto') == '0.300000000000000' assert sstr(Float(0.3), full_prec=False) == '0.3' assert sstr(Float(0.3) * x, full_prec=True) in [ '0.300000000000000*x', 'x*0.300000000000000' ] assert sstr(Float(0.3) * x, full_prec='auto') in ['0.3*x', 'x*0.3'] assert sstr(Float(0.3) * x, full_prec=False) in ['0.3*x', 'x*0.3']
def test_catalan(): n = Symbol('n', integer=True) m = Symbol('n', integer=True, positive=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs({n: i}) == c assert catalan(n).rewrite(Product).subs({n: i}).doit() == c assert catalan(x) == catalan(x) assert catalan(2 * x).rewrite(binomial) == binomial(4 * x, 2 * x) / (2 * x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8 / (3 * pi) assert catalan(Rational(1, 2)).rewrite(factorial).rewrite(gamma) ==\ 8 / (3 * pi) assert catalan(3 * x).rewrite(gamma) == 4**( 3 * x) * gamma(3 * x + Rational(1, 2)) / (sqrt(pi) * gamma(3 * x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2, ), 1) assert catalan(n).rewrite(factorial) == factorial( 2 * n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma(0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4)) * catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(Rational(1, 2)).evalf() assert str(c) == '0.848826363156775' c = catalan(I).evalf(3) assert sstr((re(c), im(c))) == '(0.398, -0.0209)' # issue sympy/sympy#8601 n = Symbol('n', integer=True, negative=True) assert catalan(n - 1) == 0 assert catalan(Rational(-1, 2)) == zoo assert catalan(-1) == Rational(-1, 2) c1 = catalan(-5.6).evalf(strict=False) assert str(c1) == '6.93334070531408e-5' c2 = catalan(-35.4).evalf(strict=False) assert str(c2) == '-4.14189164517449e-24'
def test_Permutation_Cycle(): # general principle: economically, canonically show all moved elements # and the size of the permutation. for p, s in [ (Cycle(), 'Cycle()'), (Cycle(2), 'Cycle(2)'), (Cycle(2, 1), 'Cycle(1, 2)'), (Cycle(1, 2)(5)(6, 7)(10), 'Cycle(1, 2)(6, 7)(10)'), (Cycle(3, 4)(1, 2)(3, 4), 'Cycle(1, 2)(4)'), ]: assert str(p) == s Permutation.print_cyclic = False for p, s in [ (Permutation([]), 'Permutation([])'), (Permutation([], size=1), 'Permutation([0])'), (Permutation([], size=2), 'Permutation([0, 1])'), (Permutation([], size=10), 'Permutation([], size=10)'), (Permutation([1, 0, 2]), 'Permutation([1, 0, 2])'), (Permutation([1, 0, 2, 3, 4, 5]), 'Permutation([1, 0], size=6)'), (Permutation([1, 0, 2, 3, 4, 5], size=10), 'Permutation([1, 0], size=10)'), ]: assert str(p) == s Permutation.print_cyclic = True for p, s in [ (Permutation([]), 'Permutation()'), (Permutation([], size=1), 'Permutation(0)'), (Permutation([], size=2), 'Permutation(1)'), (Permutation([], size=10), 'Permutation(9)'), (Permutation([1, 0, 2]), 'Permutation(2)(0, 1)'), (Permutation([1, 0, 2, 3, 4, 5]), 'Permutation(5)(0, 1)'), (Permutation([1, 0, 2, 3, 4, 5], size=10), 'Permutation(9)(0, 1)'), (Permutation([0, 1, 3, 2, 4, 5], size=10), 'Permutation(9)(2, 3)'), ]: assert str(p) == s assert str(AbelianGroup(3, 4)) == ('PermutationGroup([\n ' 'Permutation(6)(0, 1, 2),\n' ' Permutation(3, 4, 5, 6)])') assert sstr(Cycle(1, 2)) == repr(Cycle(1, 2))
def test_plane(): p1 = Point3D(0, 0, 0) p2 = Point3D(1, 1, 1) p3 = Point3D(1, 2, 3) p4 = Point3D(x, x, x) p5 = Point3D(y, y, y) pl3 = Plane(p1, p2, p3) pl4 = Plane(p1, normal_vector=(1, 1, 1)) pl4b = Plane(p1, p2) pl5 = Plane(p3, normal_vector=(1, 2, 3)) pl6 = Plane(Point3D(2, 3, 7), normal_vector=(2, 2, 2)) pl7 = Plane(Point3D(1, -5, -6), normal_vector=(1, -2, 1)) l1 = Line3D(Point3D(5, 0, 0), Point3D(1, -1, 1)) l2 = Line3D(Point3D(0, -2, 0), Point3D(3, 1, 1)) l3 = Line3D(Point3D(0, -1, 0), Point3D(5, -1, 9)) assert Plane(p1, p2, p3) != Plane(p1, p3, p2) assert Plane(p1, p2, p3).is_coplanar(Plane(p1, p3, p2)) assert pl3 == Plane(Point3D(0, 0, 0), normal_vector=(1, -2, 1)) assert pl3 != pl4 assert pl4 == pl4b assert pl5 == Plane(Point3D(1, 2, 3), normal_vector=(1, 2, 3)) assert pl5.equation(x, y, z) == x + 2 * y + 3 * z - 14 assert pl3.equation(x, y, z) == x - 2 * y + z assert pl3.p1 == p1 assert pl4.p1 == p1 assert pl5.p1 == p3 assert pl4.normal_vector == (1, 1, 1) assert pl5.normal_vector == (1, 2, 3) assert p1 in pl3 assert p1 in pl4 assert p3 in pl5 assert pl3.projection(Point(0, 0)) == p1 p = pl3.projection(Point3D(1, 1, 0)) assert p == Point3D(7 / 6, 2 / 3, 1 / 6) assert p in pl3 l = pl3.projection_line(Line(Point(0, 0), Point(1, 1))) assert l == Line3D(Point3D(0, 0, 0), Point3D(7 / 6, 2 / 3, 1 / 6)) assert l in pl3 # get a segment that does not intersect the plane which is also # parallel to pl3's normal veector t = Dummy() r = pl3.random_point() a = pl3.perpendicular_line(r).arbitrary_point(t) s = Segment3D(a.subs(t, 1), a.subs(t, 2)) assert s.p1 not in pl3 and s.p2 not in pl3 assert pl3.projection_line(s).equals(r) assert pl3.projection_line(Segment(Point(1, 0), Point(1, 1))) == \ Segment3D(Point3D(5/6, 1/3, -1/6), Point3D(7/6, 2/3, 1/6)) assert pl6.projection_line(Ray(Point(1, 0), Point(1, 1))) == \ Ray3D(Point3D(14/3, 11/3, 11/3), Point3D(13/3, 13/3, 10/3)) assert pl3.perpendicular_line(r.args) == pl3.perpendicular_line(r) assert pl3.is_parallel(pl6) is False assert pl4.is_parallel(pl6) assert pl6.is_parallel(l1) is False assert pl3.is_perpendicular(pl6) assert pl4.is_perpendicular(pl7) assert pl6.is_perpendicular(pl7) assert pl6.is_perpendicular(l1) is False assert pl7.distance(Point3D(1, 3, 5)) == 5 * sqrt(6) / 6 assert pl6.distance(Point3D(0, 0, 0)) == 4 * sqrt(3) assert pl6.distance(pl6.p1) == 0 assert pl7.distance(pl6) == 0 assert pl7.distance(l1) == 0 assert pl6.distance(Segment3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == 0 pl6.distance(Plane(Point3D(5, 5, 5), normal_vector=(8, 8, 8))) == sqrt(3) assert pl6.angle_between(pl3) == pi / 2 assert pl6.angle_between(pl6) == 0 assert pl6.angle_between(pl4) == 0 assert pl7.angle_between(Line3D(Point3D(2, 3, 5), Point3D(2, 4, 6))) == \ -asin(sqrt(3)/6) assert pl6.angle_between(Ray3D(Point3D(2, 4, 1), Point3D(6, 5, 3))) == \ asin(sqrt(7)/3) assert pl7.angle_between(Segment3D(Point3D(5, 6, 1), Point3D(1, 2, 4))) == \ -asin(7*sqrt(246)/246) assert are_coplanar(l1, l2, l3) is False assert are_coplanar(l1) is False assert are_coplanar(Point3D(2, 7, 2), Point3D(0, 0, 2), Point3D(1, 1, 2), Point3D(1, 2, 2)) assert are_coplanar(Plane(p1, p2, p3), Plane(p1, p3, p2)) assert Plane.are_concurrent(pl3, pl4, pl5) is False assert Plane.are_concurrent(pl6) is False pytest.raises(ValueError, lambda: Plane.are_concurrent(Point3D(0, 0, 0))) assert pl3.parallel_plane(Point3D(1, 2, 5)) == Plane(Point3D(1, 2, 5), normal_vector=(1, -2, 1)) # perpendicular_plane p = Plane((0, 0, 0), (1, 0, 0)) # default assert p.perpendicular_plane() == Plane(Point3D(0, 0, 0), (0, 1, 0)) # 1 pt assert p.perpendicular_plane(Point3D(1, 0, 1)) == \ Plane(Point3D(1, 0, 1), (0, 1, 0)) # pts as tuples assert p.perpendicular_plane((1, 0, 1), (1, 1, 1)) == \ Plane(Point3D(1, 0, 1), (0, 0, -1)) a, b = Point3D(0, 0, 0), Point3D(0, 1, 0) Z = (0, 0, 1) p = Plane(a, normal_vector=Z) # case 4 assert p.perpendicular_plane(a, b) == Plane(a, (1, 0, 0)) n = Point3D(*Z) # case 1 assert p.perpendicular_plane(a, n) == Plane(a, (-1, 0, 0)) # case 2 assert Plane(a, normal_vector=b.args).perpendicular_plane(a, a + b) == \ Plane(Point3D(0, 0, 0), (1, 0, 0)) # case 1&3 assert Plane(b, normal_vector=Z).perpendicular_plane(b, b + n) == \ Plane(Point3D(0, 1, 0), (-1, 0, 0)) # case 2&3 assert Plane(b, normal_vector=b.args).perpendicular_plane(n, n + b) == \ Plane(Point3D(0, 0, 1), (1, 0, 0)) assert pl6.intersection(pl6) == [pl6] assert pl4.intersection(pl4.p1) == [pl4.p1] assert pl3.intersection(pl6) == [ Line3D(Point3D(8, 4, 0), Point3D(2, 4, 6)) ] assert pl3.intersection(Line3D(Point3D(1, 2, 4), Point3D(4, 4, 2))) == [Point3D(2, 8 / 3, 10 / 3)] assert pl3.intersection(Plane(Point3D(6, 0, 0), normal_vector=(2, -5, 3))) == [ Line3D(Point3D(-24, -12, 0), Point3D(-25, -13, -1)) ] assert pl6.intersection(Ray3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == [Point3D(-1, 3, 10)] assert pl6.intersection(Segment3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == [Point3D(-1, 3, 10)] assert pl7.intersection(Line(Point(2, 3), Point(4, 2))) == [Point3D(13 / 2, 3 / 4, 0)] r = Ray(Point(2, 3), Point(4, 2)) assert Plane((1, 2, 0), normal_vector=(0, 0, 1)).intersection(r) == [ Ray3D(Point(2, 3), Point(4, 2)) ] assert pl3.random_point() in pl3 # issue 8570 l2 = Line3D( Point3D(Rational(50000004459633, 5000000000000), Rational(-891926590718643, 1000000000000000), Rational(231800966893633, 100000000000000)), Point3D(Rational(50000004459633, 50000000000000), Rational(-222981647679771, 250000000000000), Rational(231800966893633, 100000000000000))) p2 = Plane( Point3D(Rational(402775636372767, 100000000000000), Rational(-97224357654973, 100000000000000), Rational(216793600814789, 100000000000000)), (-Float(9.00000087501922), Float(-4.81170658872543e-13), Float(0.0))) assert sstr([i.n(2) for i in p2.intersection(l2)]) == \ '[Point3D(4.0, -0.89, 2.3)]'
def NS(e, n=15, **options): return sstr(sympify(e).evalf(n, **options), full_prec=True)
def __str__(self): from diofant import sstr return sstr(self.data) + " + " + str(self.ring.base_ideal)
def test_Geometry(): assert sstr(Point(0, 0)) == 'Point(0, 0)' assert sstr(Circle(Point(0, 0), 3)) == 'Circle(Point(0, 0), 3)'
def test_SparseMatrix(): M = SparseMatrix([[x**+1, 1], [y, x + y]]) assert str(M) == 'Matrix([\n[x, 1],\n[y, x + y]])' assert sstr(M) == 'Matrix([\n[x, 1],\n[y, x + y]])'
def test_ImmutableDenseNDimArray(): m = [2 * i + j for i in range(2) for j in range(2)] assert sstr(ImmutableDenseNDimArray(m, (2, 2))) == '[[0, 1], [2, 3]]'
def test_infinity(): assert sstr(oo * I) == 'oo*I'
def test_true_false(): assert str(true) == repr(true) == sstr(true) == 'true' assert str(false) == repr(false) == sstr(false) == 'false'
def test_PrettyPoly(): F = QQ.inject(x, y).field R = QQ.inject(x, y) assert sstr(F.convert(x / (x + y))) == sstr(x / (x + y)) assert sstr(R.convert(x + y)) == sstr(x + y)
def __repr__(self): from diofant import sstr return '[' + ', '.join(sstr(x) for x in self.data) + ']'
def sym(s): return sstr(symbols(s))
def test_settings(): pytest.raises(TypeError, lambda: sstr(Integer(4), method='garbage'))
def NS(e, n=15, **options): return sstr(sympify(e).evalf(n, **options), full_prec=True)
def test_plane(): 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)) 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)) pytest.raises(ValueError, lambda: Plane(p1, normal_vector=(1, 1))) assert Plane(p1, p2, p3) != Plane(p1, p3, p2) assert Plane(p1, p2, p3).is_coplanar(Plane(p1, p3, p2)) assert pl3 == Plane(Point3D(0, 0, 0), normal_vector=(1, -2, 1)) assert pl3 != pl4 assert pl4 == pl4b assert pl5 == Plane(Point3D(1, 2, 3), normal_vector=(1, 2, 3)) assert pl5.equation(x, y, z) == x + 2*y + 3*z - 14 assert pl3.equation(x, y, z) == x - 2*y + z assert pl3.p1 == p1 assert pl4.p1 == p1 assert pl5.p1 == p3 assert pl4.normal_vector == (1, 1, 1) assert pl5.normal_vector == (1, 2, 3) assert p1 in pl3 assert p1 in pl4 assert p3 in pl5 assert pl3.projection(Point(0, 0)) == p1 p = pl3.projection(Point3D(1, 1, 0)) assert p == Point3D(7/6, 2/3, 1/6) assert p in pl3 l = pl3.projection_line(Line(Point(0, 0), Point(1, 1))) assert l == Line3D(Point3D(0, 0, 0), Point3D(7/6, 2/3, 1/6)) assert l in pl3 # get a segment that does not intersect the plane which is also # parallel to pl3's normal veector t = Dummy() r = pl3.random_point() a = pl3.perpendicular_line(r).arbitrary_point(t) s = Segment3D(a.subs({t: 1}), a.subs({t: 2})) assert s.p1 not in pl3 and s.p2 not in pl3 assert pl3.projection_line(s).equals(r) assert pl3.projection_line(Segment(Point(1, 0), Point(1, 1))) == \ Segment3D(Point3D(5/6, 1/3, -1/6), Point3D(7/6, 2/3, 1/6)) assert pl6.projection_line(Ray(Point(1, 0), Point(1, 1))) == \ Ray3D(Point3D(14/3, 11/3, 11/3), Point3D(13/3, 13/3, 10/3)) assert pl3.perpendicular_line(r.args) == pl3.perpendicular_line(r) assert pl3.is_parallel(pl6) is False assert pl4.is_parallel(pl6) assert pl6.is_parallel(l1) is False assert pl3.is_perpendicular(pl6) assert pl4.is_perpendicular(pl7) assert pl6.is_perpendicular(pl7) assert pl6.is_perpendicular(l1) is False assert pl7.distance(Point3D(1, 3, 5)) == 5*sqrt(6)/6 assert pl6.distance(Point3D(0, 0, 0)) == 4*sqrt(3) assert pl6.distance(pl6.p1) == 0 assert pl7.distance(pl6) == 0 assert pl7.distance(l1) == 0 assert pl6.distance(Segment3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == 0 pl6.distance(Plane(Point3D(5, 5, 5), normal_vector=(8, 8, 8))) == sqrt(3) assert pl6.angle_between(pl3) == pi/2 assert pl6.angle_between(pl6) == 0 assert pl6.angle_between(pl4) == 0 assert pl7.angle_between(Line3D(Point3D(2, 3, 5), Point3D(2, 4, 6))) == \ -asin(sqrt(3)/6) assert pl6.angle_between(Ray3D(Point3D(2, 4, 1), Point3D(6, 5, 3))) == \ asin(sqrt(7)/3) assert pl7.angle_between(Segment3D(Point3D(5, 6, 1), Point3D(1, 2, 4))) == \ -asin(7*sqrt(246)/246) assert are_coplanar(l1, l2, l3) is False assert are_coplanar(l1) is False assert are_coplanar(Point3D(2, 7, 2), Point3D(0, 0, 2), Point3D(1, 1, 2), Point3D(1, 2, 2)) assert are_coplanar(Plane(p1, p2, p3), Plane(p1, p3, p2)) assert Plane.are_concurrent(pl3, pl4, pl5) is False assert Plane.are_concurrent(pl6) is False pytest.raises(ValueError, lambda: Plane.are_concurrent(Point3D(0, 0, 0))) assert pl3.parallel_plane(Point3D(1, 2, 5)) == Plane(Point3D(1, 2, 5), normal_vector=(1, -2, 1)) # perpendicular_plane p = Plane((0, 0, 0), (1, 0, 0)) # default assert p.perpendicular_plane() == Plane(Point3D(0, 0, 0), (0, 1, 0)) # 1 pt assert p.perpendicular_plane(Point3D(1, 0, 1)) == \ Plane(Point3D(1, 0, 1), (0, 1, 0)) # pts as tuples assert p.perpendicular_plane((1, 0, 1), (1, 1, 1)) == \ Plane(Point3D(1, 0, 1), (0, 0, -1)) pytest.raises(ValueError, lambda: p.perpendicular_plane(Point3D(1, 0, 1), Point3D(1, 0, 2), Point3D(1, 0, 3))) a, b = Point3D(0, 0, 0), Point3D(0, 1, 0) Z = (0, 0, 1) p = Plane(a, normal_vector=Z) # case 4 assert p.perpendicular_plane(a, b) == Plane(a, (1, 0, 0)) n = Point3D(*Z) # case 1 assert p.perpendicular_plane(a, n) == Plane(a, (-1, 0, 0)) # case 2 assert Plane(a, normal_vector=b.args).perpendicular_plane(a, a + b) == \ Plane(Point3D(0, 0, 0), (1, 0, 0)) # case 1&3 assert Plane(b, normal_vector=Z).perpendicular_plane(b, b + n) == \ Plane(Point3D(0, 1, 0), (-1, 0, 0)) # case 2&3 assert Plane(b, normal_vector=b.args).perpendicular_plane(n, n + b) == \ Plane(Point3D(0, 0, 1), (1, 0, 0)) assert pl6.intersection(pl6) == [pl6] assert pl4.intersection(pl4.p1) == [pl4.p1] assert pl3.intersection(pl6) == [ Line3D(Point3D(8, 4, 0), Point3D(2, 4, 6))] assert pl3.intersection(Line3D(Point3D(1, 2, 4), Point3D(4, 4, 2))) == [ Point3D(2, 8/3, 10/3)] assert (pl3.intersection(Plane(Point3D(6, 0, 0), normal_vector=(2, -5, 3))) == [Line3D(Point3D(-24, -12, 0), Point3D(-25, -13, -1))]) assert pl6.intersection(Ray3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == [ Point3D(-1, 3, 10)] assert pl6.intersection(Segment3D(Point3D(2, 3, 1), Point3D(1, 3, 4))) == [ Point3D(-1, 3, 10)] assert pl7.intersection(Line(Point(2, 3), Point(4, 2))) == [ Point3D(13/2, 3/4, 0)] r = Ray(Point(2, 3), Point(4, 2)) assert Plane((1, 2, 0), normal_vector=(0, 0, 1)).intersection(r) == [ Ray3D(Point(2, 3), Point(4, 2))] assert pl3.random_point() in pl3 # issue sympy/sympy#8570 l2 = Line3D(Point3D(Rational(50000004459633, 5000000000000), Rational(-891926590718643, 1000000000000000), Rational(231800966893633, 100000000000000)), Point3D(Rational(50000004459633, 50000000000000), Rational(-222981647679771, 250000000000000), Rational(231800966893633, 100000000000000))) p2 = Plane(Point3D(Rational(402775636372767, 100000000000000), Rational(-97224357654973, 100000000000000), Rational(216793600814789, 100000000000000)), (-Float(9.00000087501922), Float(-4.81170658872543e-13), Float(0.0))) assert sstr([i.evalf(2) for i in p2.intersection(l2)]) == \ '[Point3D(4.0, -0.89, 2.3)]'