m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

826 lines
36 KiB

6 months ago
  1. from sympy.core.numbers import (Float, Rational, oo, pi)
  2. from sympy.core.relational import Eq
  3. from sympy.core.singleton import S
  4. from sympy.core.symbol import (Symbol, symbols)
  5. from sympy.functions.elementary.miscellaneous import sqrt
  6. from sympy.functions.elementary.trigonometric import (acos, cos, sin)
  7. from sympy.sets import EmptySet
  8. from sympy.simplify.simplify import simplify
  9. from sympy.functions.elementary.trigonometric import tan
  10. from sympy.geometry import (Circle, GeometryError, Line, Point, Ray,
  11. Segment, Triangle, intersection, Point3D, Line3D, Ray3D, Segment3D,
  12. Point2D, Line2D)
  13. from sympy.geometry.line import Undecidable
  14. from sympy.geometry.polygon import _asa as asa
  15. from sympy.utilities.iterables import cartes
  16. from sympy.testing.pytest import raises, warns, warns_deprecated_sympy
  17. x = Symbol('x', real=True)
  18. y = Symbol('y', real=True)
  19. z = Symbol('z', real=True)
  20. k = Symbol('k', real=True)
  21. x1 = Symbol('x1', real=True)
  22. y1 = Symbol('y1', real=True)
  23. t = Symbol('t', real=True)
  24. a, b = symbols('a,b', real=True)
  25. m = symbols('m', real=True)
  26. def test_object_from_equation():
  27. from sympy.abc import x, y, a, b
  28. assert Line(3*x + y + 18) == Line2D(Point2D(0, -18), Point2D(1, -21))
  29. assert Line(3*x + 5 * y + 1) == Line2D(
  30. Point2D(0, Rational(-1, 5)), Point2D(1, Rational(-4, 5)))
  31. assert Line(3*a + b + 18, x="a", y="b") == Line2D(
  32. Point2D(0, -18), Point2D(1, -21))
  33. assert Line(3*x + y) == Line2D(Point2D(0, 0), Point2D(1, -3))
  34. assert Line(x + y) == Line2D(Point2D(0, 0), Point2D(1, -1))
  35. assert Line(Eq(3*a + b, -18), x="a", y=b) == Line2D(
  36. Point2D(0, -18), Point2D(1, -21))
  37. # issue 22361
  38. assert Line(x - 1) == Line2D(Point2D(1, 0), Point2D(1, 1))
  39. assert Line(2*x - 2, y=x) == Line2D(Point2D(0, 1), Point2D(1, 1))
  40. assert Line(y) == Line2D(Point2D(0, 0), Point2D(1, 0))
  41. assert Line(2*y, x=y) == Line2D(Point2D(0, 0), Point2D(0, 1))
  42. assert Line(y, x=y) == Line2D(Point2D(0, 0), Point2D(0, 1))
  43. raises(ValueError, lambda: Line(x / y))
  44. raises(ValueError, lambda: Line(a / b, x='a', y='b'))
  45. raises(ValueError, lambda: Line(y / x))
  46. raises(ValueError, lambda: Line(b / a, x='a', y='b'))
  47. raises(ValueError, lambda: Line((x + 1)**2 + y))
  48. def feq(a, b):
  49. """Test if two floating point values are 'equal'."""
  50. t_float = Float("1.0E-10")
  51. return -t_float < a - b < t_float
  52. def test_angle_between():
  53. a = Point(1, 2, 3, 4)
  54. b = a.orthogonal_direction
  55. o = a.origin
  56. assert feq(Line.angle_between(Line(Point(0, 0), Point(1, 1)),
  57. Line(Point(0, 0), Point(5, 0))).evalf(), pi.evalf() / 4)
  58. assert Line(a, o).angle_between(Line(b, o)) == pi / 2
  59. assert Line3D.angle_between(Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1)),
  60. Line3D(Point3D(0, 0, 0), Point3D(5, 0, 0))) == acos(sqrt(3) / 3)
  61. def test_closing_angle():
  62. a = Ray((0, 0), angle=0)
  63. b = Ray((1, 2), angle=pi/2)
  64. assert a.closing_angle(b) == -pi/2
  65. assert b.closing_angle(a) == pi/2
  66. assert a.closing_angle(a) == 0
  67. def test_smallest_angle():
  68. a = Line(Point(1, 1), Point(1, 2))
  69. b = Line(Point(1, 1),Point(2, 3))
  70. assert a.smallest_angle_between(b) == acos(2*sqrt(5)/5)
  71. def test_svg():
  72. a = Line(Point(1, 1),Point(1, 2))
  73. assert a._svg() == '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 1.00000000000000,1.00000000000000 L 1.00000000000000,2.00000000000000" marker-start="url(#markerReverseArrow)" marker-end="url(#markerArrow)"/>'
  74. a = Segment(Point(1, 0),Point(1, 1))
  75. assert a._svg() == '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 1.00000000000000,0 L 1.00000000000000,1.00000000000000" />'
  76. a = Ray(Point(2, 3), Point(3, 5))
  77. assert a._svg() == '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 2.00000000000000,3.00000000000000 L 3.00000000000000,5.00000000000000" marker-start="url(#markerCircle)" marker-end="url(#markerArrow)"/>'
  78. def test_arbitrary_point():
  79. l1 = Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1))
  80. l2 = Line(Point(x1, x1), Point(y1, y1))
  81. assert l2.arbitrary_point() in l2
  82. assert Ray((1, 1), angle=pi / 4).arbitrary_point() == \
  83. Point(t + 1, t + 1)
  84. assert Segment((1, 1), (2, 3)).arbitrary_point() == Point(1 + t, 1 + 2 * t)
  85. assert l1.perpendicular_segment(l1.arbitrary_point()) == l1.arbitrary_point()
  86. assert Ray3D((1, 1, 1), direction_ratio=[1, 2, 3]).arbitrary_point() == \
  87. Point3D(t + 1, 2 * t + 1, 3 * t + 1)
  88. assert Segment3D(Point3D(0, 0, 0), Point3D(1, 1, 1)).midpoint == \
  89. Point3D(S.Half, S.Half, S.Half)
  90. assert Segment3D(Point3D(x1, x1, x1), Point3D(y1, y1, y1)).length == sqrt(3) * sqrt((x1 - y1) ** 2)
  91. assert Segment3D((1, 1, 1), (2, 3, 4)).arbitrary_point() == \
  92. Point3D(t + 1, 2 * t + 1, 3 * t + 1)
  93. raises(ValueError, (lambda: Line((x, 1), (2, 3)).arbitrary_point(x)))
  94. def test_are_concurrent_2d():
  95. l1 = Line(Point(0, 0), Point(1, 1))
  96. l2 = Line(Point(x1, x1), Point(x1, 1 + x1))
  97. assert Line.are_concurrent(l1) is False
  98. assert Line.are_concurrent(l1, l2)
  99. assert Line.are_concurrent(l1, l1, l1, l2)
  100. assert Line.are_concurrent(l1, l2, Line(Point(5, x1), Point(Rational(-3, 5), x1)))
  101. assert Line.are_concurrent(l1, Line(Point(0, 0), Point(-x1, x1)), l2) is False
  102. def test_are_concurrent_3d():
  103. p1 = Point3D(0, 0, 0)
  104. l1 = Line(p1, Point3D(1, 1, 1))
  105. parallel_1 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))
  106. parallel_2 = Line3D(Point3D(0, 1, 0), Point3D(1, 1, 0))
  107. assert Line3D.are_concurrent(l1) is False
  108. assert Line3D.are_concurrent(l1, Line(Point3D(x1, x1, x1), Point3D(y1, y1, y1))) is False
  109. assert Line3D.are_concurrent(l1, Line3D(p1, Point3D(x1, x1, x1)),
  110. Line(Point3D(x1, x1, x1), Point3D(x1, 1 + x1, 1))) is True
  111. assert Line3D.are_concurrent(parallel_1, parallel_2) is False
  112. def test_arguments():
  113. """Functions accepting `Point` objects in `geometry`
  114. should also accept tuples, lists, and generators and
  115. automatically convert them to points."""
  116. from sympy.utilities.iterables import subsets
  117. singles2d = ((1, 2), [1, 3], Point(1, 5))
  118. doubles2d = subsets(singles2d, 2)
  119. l2d = Line(Point2D(1, 2), Point2D(2, 3))
  120. singles3d = ((1, 2, 3), [1, 2, 4], Point(1, 2, 6))
  121. doubles3d = subsets(singles3d, 2)
  122. l3d = Line(Point3D(1, 2, 3), Point3D(1, 1, 2))
  123. singles4d = ((1, 2, 3, 4), [1, 2, 3, 5], Point(1, 2, 3, 7))
  124. doubles4d = subsets(singles4d, 2)
  125. l4d = Line(Point(1, 2, 3, 4), Point(2, 2, 2, 2))
  126. # test 2D
  127. test_single = ['contains', 'distance', 'equals', 'parallel_line', 'perpendicular_line', 'perpendicular_segment',
  128. 'projection', 'intersection']
  129. for p in doubles2d:
  130. Line2D(*p)
  131. for func in test_single:
  132. for p in singles2d:
  133. getattr(l2d, func)(p)
  134. # test 3D
  135. for p in doubles3d:
  136. Line3D(*p)
  137. for func in test_single:
  138. for p in singles3d:
  139. getattr(l3d, func)(p)
  140. # test 4D
  141. for p in doubles4d:
  142. Line(*p)
  143. for func in test_single:
  144. for p in singles4d:
  145. getattr(l4d, func)(p)
  146. def test_basic_properties_2d():
  147. p1 = Point(0, 0)
  148. p2 = Point(1, 1)
  149. p10 = Point(2000, 2000)
  150. p_r3 = Ray(p1, p2).random_point()
  151. p_r4 = Ray(p2, p1).random_point()
  152. l1 = Line(p1, p2)
  153. l3 = Line(Point(x1, x1), Point(x1, 1 + x1))
  154. l4 = Line(p1, Point(1, 0))
  155. r1 = Ray(p1, Point(0, 1))
  156. r2 = Ray(Point(0, 1), p1)
  157. s1 = Segment(p1, p10)
  158. p_s1 = s1.random_point()
  159. assert Line((1, 1), slope=1) == Line((1, 1), (2, 2))
  160. assert Line((1, 1), slope=oo) == Line((1, 1), (1, 2))
  161. assert Line((1, 1), slope=oo).bounds == (1, 1, 1, 2)
  162. assert Line((1, 1), slope=-oo) == Line((1, 1), (1, 2))
  163. assert Line(p1, p2).scale(2, 1) == Line(p1, Point(2, 1))
  164. assert Line(p1, p2) == Line(p1, p2)
  165. assert Line(p1, p2) != Line(p2, p1)
  166. assert l1 != Line(Point(x1, x1), Point(y1, y1))
  167. assert l1 != l3
  168. assert Line(p1, p10) != Line(p10, p1)
  169. assert Line(p1, p10) != p1
  170. assert p1 in l1 # is p1 on the line l1?
  171. assert p1 not in l3
  172. assert s1 in Line(p1, p10)
  173. assert Ray(Point(0, 0), Point(0, 1)) in Ray(Point(0, 0), Point(0, 2))
  174. assert Ray(Point(0, 0), Point(0, 2)) in Ray(Point(0, 0), Point(0, 1))
  175. assert Ray(Point(0, 0), Point(0, 2)).xdirection == S.Zero
  176. assert Ray(Point(0, 0), Point(1, 2)).xdirection == S.Infinity
  177. assert Ray(Point(0, 0), Point(-1, 2)).xdirection == S.NegativeInfinity
  178. assert Ray(Point(0, 0), Point(2, 0)).ydirection == S.Zero
  179. assert Ray(Point(0, 0), Point(2, 2)).ydirection == S.Infinity
  180. assert Ray(Point(0, 0), Point(2, -2)).ydirection == S.NegativeInfinity
  181. assert (r1 in s1) is False
  182. assert Segment(p1, p2) in s1
  183. assert Ray(Point(x1, x1), Point(x1, 1 + x1)) != Ray(p1, Point(-1, 5))
  184. assert Segment(p1, p2).midpoint == Point(S.Half, S.Half)
  185. assert Segment(p1, Point(-x1, x1)).length == sqrt(2 * (x1 ** 2))
  186. assert l1.slope == 1
  187. assert l3.slope is oo
  188. assert l4.slope == 0
  189. assert Line(p1, Point(0, 1)).slope is oo
  190. assert Line(r1.source, r1.random_point()).slope == r1.slope
  191. assert Line(r2.source, r2.random_point()).slope == r2.slope
  192. assert Segment(Point(0, -1), Segment(p1, Point(0, 1)).random_point()).slope == Segment(p1, Point(0, 1)).slope
  193. assert l4.coefficients == (0, 1, 0)
  194. assert Line((-x, x), (-x + 1, x - 1)).coefficients == (1, 1, 0)
  195. assert Line(p1, Point(0, 1)).coefficients == (1, 0, 0)
  196. # issue 7963
  197. r = Ray((0, 0), angle=x)
  198. assert r.subs(x, 3 * pi / 4) == Ray((0, 0), (-1, 1))
  199. assert r.subs(x, 5 * pi / 4) == Ray((0, 0), (-1, -1))
  200. assert r.subs(x, -pi / 4) == Ray((0, 0), (1, -1))
  201. assert r.subs(x, pi / 2) == Ray((0, 0), (0, 1))
  202. assert r.subs(x, -pi / 2) == Ray((0, 0), (0, -1))
  203. for ind in range(0, 5):
  204. assert l3.random_point() in l3
  205. assert p_r3.x >= p1.x and p_r3.y >= p1.y
  206. assert p_r4.x <= p2.x and p_r4.y <= p2.y
  207. assert p1.x <= p_s1.x <= p10.x and p1.y <= p_s1.y <= p10.y
  208. assert hash(s1) != hash(Segment(p10, p1))
  209. assert s1.plot_interval() == [t, 0, 1]
  210. assert Line(p1, p10).plot_interval() == [t, -5, 5]
  211. assert Ray((0, 0), angle=pi / 4).plot_interval() == [t, 0, 10]
  212. def test_basic_properties_3d():
  213. p1 = Point3D(0, 0, 0)
  214. p2 = Point3D(1, 1, 1)
  215. p3 = Point3D(x1, x1, x1)
  216. p5 = Point3D(x1, 1 + x1, 1)
  217. l1 = Line3D(p1, p2)
  218. l3 = Line3D(p3, p5)
  219. r1 = Ray3D(p1, Point3D(-1, 5, 0))
  220. r3 = Ray3D(p1, p2)
  221. s1 = Segment3D(p1, p2)
  222. assert Line3D((1, 1, 1), direction_ratio=[2, 3, 4]) == Line3D(Point3D(1, 1, 1), Point3D(3, 4, 5))
  223. assert Line3D((1, 1, 1), direction_ratio=[1, 5, 7]) == Line3D(Point3D(1, 1, 1), Point3D(2, 6, 8))
  224. assert Line3D((1, 1, 1), direction_ratio=[1, 2, 3]) == Line3D(Point3D(1, 1, 1), Point3D(2, 3, 4))
  225. assert Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).direction_cosine == [1, 0, 0]
  226. assert Line3D(Line3D(p1, Point3D(0, 1, 0))) == Line3D(p1, Point3D(0, 1, 0))
  227. assert Ray3D(Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))) == Ray3D(p1, Point3D(1, 0, 0))
  228. assert Line3D(p1, p2) != Line3D(p2, p1)
  229. assert l1 != l3
  230. assert l1 != Line3D(p3, Point3D(y1, y1, y1))
  231. assert r3 != r1
  232. assert Ray3D(Point3D(0, 0, 0), Point3D(1, 1, 1)) in Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2))
  233. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)) in Ray3D(Point3D(0, 0, 0), Point3D(1, 1, 1))
  234. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)).xdirection == S.Infinity
  235. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)).ydirection == S.Infinity
  236. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 2)).zdirection == S.Infinity
  237. assert Ray3D(Point3D(0, 0, 0), Point3D(-2, 2, 2)).xdirection == S.NegativeInfinity
  238. assert Ray3D(Point3D(0, 0, 0), Point3D(2, -2, 2)).ydirection == S.NegativeInfinity
  239. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, -2)).zdirection == S.NegativeInfinity
  240. assert Ray3D(Point3D(0, 0, 0), Point3D(0, 2, 2)).xdirection == S.Zero
  241. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 0, 2)).ydirection == S.Zero
  242. assert Ray3D(Point3D(0, 0, 0), Point3D(2, 2, 0)).zdirection == S.Zero
  243. assert p1 in l1
  244. assert p1 not in l3
  245. assert l1.direction_ratio == [1, 1, 1]
  246. assert s1.midpoint == Point3D(S.Half, S.Half, S.Half)
  247. # Test zdirection
  248. assert Ray3D(p1, Point3D(0, 0, -1)).zdirection is S.NegativeInfinity
  249. def test_contains():
  250. p1 = Point(0, 0)
  251. r = Ray(p1, Point(4, 4))
  252. r1 = Ray3D(p1, Point3D(0, 0, -1))
  253. r2 = Ray3D(p1, Point3D(0, 1, 0))
  254. r3 = Ray3D(p1, Point3D(0, 0, 1))
  255. l = Line(Point(0, 1), Point(3, 4))
  256. # Segment contains
  257. assert Point(0, (a + b) / 2) in Segment((0, a), (0, b))
  258. assert Point((a + b) / 2, 0) in Segment((a, 0), (b, 0))
  259. assert Point3D(0, 1, 0) in Segment3D((0, 1, 0), (0, 1, 0))
  260. assert Point3D(1, 0, 0) in Segment3D((1, 0, 0), (1, 0, 0))
  261. assert Segment3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).contains([]) is True
  262. assert Segment3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).contains(
  263. Segment3D(Point3D(2, 2, 2), Point3D(3, 2, 2))) is False
  264. # Line contains
  265. assert l.contains(Point(0, 1)) is True
  266. assert l.contains((0, 1)) is True
  267. assert l.contains((0, 0)) is False
  268. # Ray contains
  269. assert r.contains(p1) is True
  270. assert r.contains((1, 1)) is True
  271. assert r.contains((1, 3)) is False
  272. assert r.contains(Segment((1, 1), (2, 2))) is True
  273. assert r.contains(Segment((1, 2), (2, 5))) is False
  274. assert r.contains(Ray((2, 2), (3, 3))) is True
  275. assert r.contains(Ray((2, 2), (3, 5))) is False
  276. assert r1.contains(Segment3D(p1, Point3D(0, 0, -10))) is True
  277. assert r1.contains(Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))) is False
  278. assert r2.contains(Point3D(0, 0, 0)) is True
  279. assert r3.contains(Point3D(0, 0, 0)) is True
  280. assert Ray3D(Point3D(1, 1, 1), Point3D(1, 0, 0)).contains([]) is False
  281. assert Line3D((0, 0, 0), (x, y, z)).contains((2 * x, 2 * y, 2 * z))
  282. with warns(UserWarning, test_stacklevel=False):
  283. assert Line3D(p1, Point3D(0, 1, 0)).contains(Point(1.0, 1.0)) is False
  284. with warns(UserWarning, test_stacklevel=False):
  285. assert r3.contains(Point(1.0, 1.0)) is False
  286. def test_contains_nonreal_symbols():
  287. u, v, w, z = symbols('u, v, w, z')
  288. l = Segment(Point(u, w), Point(v, z))
  289. p = Point(u*Rational(2, 3) + v/3, w*Rational(2, 3) + z/3)
  290. assert l.contains(p)
  291. def test_distance_2d():
  292. p1 = Point(0, 0)
  293. p2 = Point(1, 1)
  294. half = S.Half
  295. s1 = Segment(Point(0, 0), Point(1, 1))
  296. s2 = Segment(Point(half, half), Point(1, 0))
  297. r = Ray(p1, p2)
  298. assert s1.distance(Point(0, 0)) == 0
  299. assert s1.distance((0, 0)) == 0
  300. assert s2.distance(Point(0, 0)) == 2 ** half / 2
  301. assert s2.distance(Point(Rational(3) / 2, Rational(3) / 2)) == 2 ** half
  302. assert Line(p1, p2).distance(Point(-1, 1)) == sqrt(2)
  303. assert Line(p1, p2).distance(Point(1, -1)) == sqrt(2)
  304. assert Line(p1, p2).distance(Point(2, 2)) == 0
  305. assert Line(p1, p2).distance((-1, 1)) == sqrt(2)
  306. assert Line((0, 0), (0, 1)).distance(p1) == 0
  307. assert Line((0, 0), (0, 1)).distance(p2) == 1
  308. assert Line((0, 0), (1, 0)).distance(p1) == 0
  309. assert Line((0, 0), (1, 0)).distance(p2) == 1
  310. assert r.distance(Point(-1, -1)) == sqrt(2)
  311. assert r.distance(Point(1, 1)) == 0
  312. assert r.distance(Point(-1, 1)) == sqrt(2)
  313. assert Ray((1, 1), (2, 2)).distance(Point(1.5, 3)) == 3 * sqrt(2) / 4
  314. assert r.distance((1, 1)) == 0
  315. def test_dimension_normalization():
  316. with warns(UserWarning, test_stacklevel=False):
  317. assert Ray((1, 1), (2, 1, 2)) == Ray((1, 1, 0), (2, 1, 2))
  318. def test_distance_3d():
  319. p1, p2 = Point3D(0, 0, 0), Point3D(1, 1, 1)
  320. p3 = Point3D(Rational(3) / 2, Rational(3) / 2, Rational(3) / 2)
  321. s1 = Segment3D(Point3D(0, 0, 0), Point3D(1, 1, 1))
  322. s2 = Segment3D(Point3D(S.Half, S.Half, S.Half), Point3D(1, 0, 1))
  323. r = Ray3D(p1, p2)
  324. assert s1.distance(p1) == 0
  325. assert s2.distance(p1) == sqrt(3) / 2
  326. assert s2.distance(p3) == 2 * sqrt(6) / 3
  327. assert s1.distance((0, 0, 0)) == 0
  328. assert s2.distance((0, 0, 0)) == sqrt(3) / 2
  329. assert s1.distance(p1) == 0
  330. assert s2.distance(p1) == sqrt(3) / 2
  331. assert s2.distance(p3) == 2 * sqrt(6) / 3
  332. assert s1.distance((0, 0, 0)) == 0
  333. assert s2.distance((0, 0, 0)) == sqrt(3) / 2
  334. # Line to point
  335. assert Line3D(p1, p2).distance(Point3D(-1, 1, 1)) == 2 * sqrt(6) / 3
  336. assert Line3D(p1, p2).distance(Point3D(1, -1, 1)) == 2 * sqrt(6) / 3
  337. assert Line3D(p1, p2).distance(Point3D(2, 2, 2)) == 0
  338. assert Line3D(p1, p2).distance((2, 2, 2)) == 0
  339. assert Line3D(p1, p2).distance((1, -1, 1)) == 2 * sqrt(6) / 3
  340. assert Line3D((0, 0, 0), (0, 1, 0)).distance(p1) == 0
  341. assert Line3D((0, 0, 0), (0, 1, 0)).distance(p2) == sqrt(2)
  342. assert Line3D((0, 0, 0), (1, 0, 0)).distance(p1) == 0
  343. assert Line3D((0, 0, 0), (1, 0, 0)).distance(p2) == sqrt(2)
  344. # Ray to point
  345. assert r.distance(Point3D(-1, -1, -1)) == sqrt(3)
  346. assert r.distance(Point3D(1, 1, 1)) == 0
  347. assert r.distance((-1, -1, -1)) == sqrt(3)
  348. assert r.distance((1, 1, 1)) == 0
  349. assert Ray3D((0, 0, 0), (1, 1, 2)).distance((-1, -1, 2)) == 4 * sqrt(3) / 3
  350. assert Ray3D((1, 1, 1), (2, 2, 2)).distance(Point3D(1.5, -3, -1)) == Rational(9) / 2
  351. assert Ray3D((1, 1, 1), (2, 2, 2)).distance(Point3D(1.5, 3, 1)) == sqrt(78) / 6
  352. def test_equals():
  353. p1 = Point(0, 0)
  354. p2 = Point(1, 1)
  355. l1 = Line(p1, p2)
  356. l2 = Line((0, 5), slope=m)
  357. l3 = Line(Point(x1, x1), Point(x1, 1 + x1))
  358. assert l1.perpendicular_line(p1.args).equals(Line(Point(0, 0), Point(1, -1)))
  359. assert l1.perpendicular_line(p1).equals(Line(Point(0, 0), Point(1, -1)))
  360. assert Line(Point(x1, x1), Point(y1, y1)).parallel_line(Point(-x1, x1)). \
  361. equals(Line(Point(-x1, x1), Point(-y1, 2 * x1 - y1)))
  362. assert l3.parallel_line(p1.args).equals(Line(Point(0, 0), Point(0, -1)))
  363. assert l3.parallel_line(p1).equals(Line(Point(0, 0), Point(0, -1)))
  364. assert (l2.distance(Point(2, 3)) - 2 * abs(m + 1) / sqrt(m ** 2 + 1)).equals(0)
  365. assert Line3D(p1, Point3D(0, 1, 0)).equals(Point(1.0, 1.0)) is False
  366. assert Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).equals(Line3D(Point3D(-5, 0, 0), Point3D(-1, 0, 0))) is True
  367. assert Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)).equals(Line3D(p1, Point3D(0, 1, 0))) is False
  368. assert Ray3D(p1, Point3D(0, 0, -1)).equals(Point(1.0, 1.0)) is False
  369. assert Ray3D(p1, Point3D(0, 0, -1)).equals(Ray3D(p1, Point3D(0, 0, -1))) is True
  370. assert Line3D((0, 0), (t, t)).perpendicular_line(Point(0, 1, 0)).equals(
  371. Line3D(Point3D(0, 1, 0), Point3D(S.Half, S.Half, 0)))
  372. assert Line3D((0, 0), (t, t)).perpendicular_segment(Point(0, 1, 0)).equals(Segment3D((0, 1), (S.Half, S.Half)))
  373. assert Line3D(p1, Point3D(0, 1, 0)).equals(Point(1.0, 1.0)) is False
  374. def test_equation():
  375. p1 = Point(0, 0)
  376. p2 = Point(1, 1)
  377. l1 = Line(p1, p2)
  378. l3 = Line(Point(x1, x1), Point(x1, 1 + x1))
  379. assert simplify(l1.equation()) in (x - y, y - x)
  380. assert simplify(l3.equation()) in (x - x1, x1 - x)
  381. assert simplify(l1.equation()) in (x - y, y - x)
  382. assert simplify(l3.equation()) in (x - x1, x1 - x)
  383. assert Line(p1, Point(1, 0)).equation(x=x, y=y) == y
  384. assert Line(p1, Point(0, 1)).equation() == x
  385. assert Line(Point(2, 0), Point(2, 1)).equation() == x - 2
  386. assert Line(p2, Point(2, 1)).equation() == y - 1
  387. assert Line3D(Point(x1, x1, x1), Point(y1, y1, y1)
  388. ).equation() == (-x + y, -x + z)
  389. assert Line3D(Point(1, 2, 3), Point(2, 3, 4)
  390. ).equation() == (-x + y - 1, -x + z - 2)
  391. assert Line3D(Point(1, 2, 3), Point(1, 3, 4)
  392. ).equation() == (x - 1, -y + z - 1)
  393. assert Line3D(Point(1, 2, 3), Point(2, 2, 4)
  394. ).equation() == (y - 2, -x + z - 2)
  395. assert Line3D(Point(1, 2, 3), Point(2, 3, 3)
  396. ).equation() == (-x + y - 1, z - 3)
  397. assert Line3D(Point(1, 2, 3), Point(1, 2, 4)
  398. ).equation() == (x - 1, y - 2)
  399. assert Line3D(Point(1, 2, 3), Point(1, 3, 3)
  400. ).equation() == (x - 1, z - 3)
  401. assert Line3D(Point(1, 2, 3), Point(2, 2, 3)
  402. ).equation() == (y - 2, z - 3)
  403. with warns_deprecated_sympy():
  404. assert Line3D(Point(1, 2, 3), Point(2, 2, 3)
  405. ).equation(k='k') == (y - 2, z - 3)
  406. def test_intersection_2d():
  407. p1 = Point(0, 0)
  408. p2 = Point(1, 1)
  409. p3 = Point(x1, x1)
  410. p4 = Point(y1, y1)
  411. l1 = Line(p1, p2)
  412. l3 = Line(Point(0, 0), Point(3, 4))
  413. r1 = Ray(Point(1, 1), Point(2, 2))
  414. r2 = Ray(Point(0, 0), Point(3, 4))
  415. r4 = Ray(p1, p2)
  416. r6 = Ray(Point(0, 1), Point(1, 2))
  417. r7 = Ray(Point(0.5, 0.5), Point(1, 1))
  418. s1 = Segment(p1, p2)
  419. s2 = Segment(Point(0.25, 0.25), Point(0.5, 0.5))
  420. s3 = Segment(Point(0, 0), Point(3, 4))
  421. assert intersection(l1, p1) == [p1]
  422. assert intersection(l1, Point(x1, 1 + x1)) == []
  423. assert intersection(l1, Line(p3, p4)) in [[l1], [Line(p3, p4)]]
  424. assert intersection(l1, l1.parallel_line(Point(x1, 1 + x1))) == []
  425. assert intersection(l3, l3) == [l3]
  426. assert intersection(l3, r2) == [r2]
  427. assert intersection(l3, s3) == [s3]
  428. assert intersection(s3, l3) == [s3]
  429. assert intersection(Segment(Point(-10, 10), Point(10, 10)), Segment(Point(-5, -5), Point(-5, 5))) == []
  430. assert intersection(r2, l3) == [r2]
  431. assert intersection(r1, Ray(Point(2, 2), Point(0, 0))) == [Segment(Point(1, 1), Point(2, 2))]
  432. assert intersection(r1, Ray(Point(1, 1), Point(-1, -1))) == [Point(1, 1)]
  433. assert intersection(r1, Segment(Point(0, 0), Point(2, 2))) == [Segment(Point(1, 1), Point(2, 2))]
  434. assert r4.intersection(s2) == [s2]
  435. assert r4.intersection(Segment(Point(2, 3), Point(3, 4))) == []
  436. assert r4.intersection(Segment(Point(-1, -1), Point(0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))]
  437. assert r4.intersection(Ray(p2, p1)) == [s1]
  438. assert Ray(p2, p1).intersection(r6) == []
  439. assert r4.intersection(r7) == r7.intersection(r4) == [r7]
  440. assert Ray3D((0, 0), (3, 0)).intersection(Ray3D((1, 0), (3, 0))) == [Ray3D((1, 0), (3, 0))]
  441. assert Ray3D((1, 0), (3, 0)).intersection(Ray3D((0, 0), (3, 0))) == [Ray3D((1, 0), (3, 0))]
  442. assert Ray(Point(0, 0), Point(0, 4)).intersection(Ray(Point(0, 1), Point(0, -1))) == \
  443. [Segment(Point(0, 0), Point(0, 1))]
  444. assert Segment3D((0, 0), (3, 0)).intersection(
  445. Segment3D((1, 0), (2, 0))) == [Segment3D((1, 0), (2, 0))]
  446. assert Segment3D((1, 0), (2, 0)).intersection(
  447. Segment3D((0, 0), (3, 0))) == [Segment3D((1, 0), (2, 0))]
  448. assert Segment3D((0, 0), (3, 0)).intersection(
  449. Segment3D((3, 0), (4, 0))) == [Point3D((3, 0))]
  450. assert Segment3D((0, 0), (3, 0)).intersection(
  451. Segment3D((2, 0), (5, 0))) == [Segment3D((2, 0), (3, 0))]
  452. assert Segment3D((0, 0), (3, 0)).intersection(
  453. Segment3D((-2, 0), (1, 0))) == [Segment3D((0, 0), (1, 0))]
  454. assert Segment3D((0, 0), (3, 0)).intersection(
  455. Segment3D((-2, 0), (0, 0))) == [Point3D(0, 0)]
  456. assert s1.intersection(Segment(Point(1, 1), Point(2, 2))) == [Point(1, 1)]
  457. assert s1.intersection(Segment(Point(0.5, 0.5), Point(1.5, 1.5))) == [Segment(Point(0.5, 0.5), p2)]
  458. assert s1.intersection(Segment(Point(4, 4), Point(5, 5))) == []
  459. assert s1.intersection(Segment(Point(-1, -1), p1)) == [p1]
  460. assert s1.intersection(Segment(Point(-1, -1), Point(0.5, 0.5))) == [Segment(p1, Point(0.5, 0.5))]
  461. assert s1.intersection(Line(Point(1, 0), Point(2, 1))) == []
  462. assert s1.intersection(s2) == [s2]
  463. assert s2.intersection(s1) == [s2]
  464. assert asa(120, 8, 52) == \
  465. Triangle(
  466. Point(0, 0),
  467. Point(8, 0),
  468. Point(-4 * cos(19 * pi / 90) / sin(2 * pi / 45),
  469. 4 * sqrt(3) * cos(19 * pi / 90) / sin(2 * pi / 45)))
  470. assert Line((0, 0), (1, 1)).intersection(Ray((1, 0), (1, 2))) == [Point(1, 1)]
  471. assert Line((0, 0), (1, 1)).intersection(Segment((1, 0), (1, 2))) == [Point(1, 1)]
  472. assert Ray((0, 0), (1, 1)).intersection(Ray((1, 0), (1, 2))) == [Point(1, 1)]
  473. assert Ray((0, 0), (1, 1)).intersection(Segment((1, 0), (1, 2))) == [Point(1, 1)]
  474. assert Ray((0, 0), (10, 10)).contains(Segment((1, 1), (2, 2))) is True
  475. assert Segment((1, 1), (2, 2)) in Line((0, 0), (10, 10))
  476. assert s1.intersection(Ray((1, 1), (4, 4))) == [Point(1, 1)]
  477. # This test is disabled because it hangs after rref changes which simplify
  478. # intermediate results and return a different representation from when the
  479. # test was written.
  480. # # 16628 - this should be fast
  481. # p0 = Point2D(Rational(249, 5), Rational(497999, 10000))
  482. # p1 = Point2D((-58977084786*sqrt(405639795226) + 2030690077184193 +
  483. # 20112207807*sqrt(630547164901) + 99600*sqrt(255775022850776494562626))
  484. # /(2000*sqrt(255775022850776494562626) + 1991998000*sqrt(405639795226)
  485. # + 1991998000*sqrt(630547164901) + 1622561172902000),
  486. # (-498000*sqrt(255775022850776494562626) - 995999*sqrt(630547164901) +
  487. # 90004251917891999 +
  488. # 496005510002*sqrt(405639795226))/(10000*sqrt(255775022850776494562626)
  489. # + 9959990000*sqrt(405639795226) + 9959990000*sqrt(630547164901) +
  490. # 8112805864510000))
  491. # p2 = Point2D(Rational(497, 10), Rational(-497, 10))
  492. # p3 = Point2D(Rational(-497, 10), Rational(-497, 10))
  493. # l = Line(p0, p1)
  494. # s = Segment(p2, p3)
  495. # n = (-52673223862*sqrt(405639795226) - 15764156209307469 -
  496. # 9803028531*sqrt(630547164901) +
  497. # 33200*sqrt(255775022850776494562626))
  498. # d = sqrt(405639795226) + 315274080450 + 498000*sqrt(
  499. # 630547164901) + sqrt(255775022850776494562626)
  500. # assert intersection(l, s) == [
  501. # Point2D(n/d*Rational(3, 2000), Rational(-497, 10))]
  502. def test_line_intersection():
  503. # see also test_issue_11238 in test_matrices.py
  504. x0 = tan(pi*Rational(13, 45))
  505. x1 = sqrt(3)
  506. x2 = x0**2
  507. x, y = [8*x0/(x0 + x1), (24*x0 - 8*x1*x2)/(x2 - 3)]
  508. assert Line(Point(0, 0), Point(1, -sqrt(3))).contains(Point(x, y)) is True
  509. def test_intersection_3d():
  510. p1 = Point3D(0, 0, 0)
  511. p2 = Point3D(1, 1, 1)
  512. l1 = Line3D(p1, p2)
  513. l2 = Line3D(Point3D(0, 0, 0), Point3D(3, 4, 0))
  514. r1 = Ray3D(Point3D(1, 1, 1), Point3D(2, 2, 2))
  515. r2 = Ray3D(Point3D(0, 0, 0), Point3D(3, 4, 0))
  516. s1 = Segment3D(Point3D(0, 0, 0), Point3D(3, 4, 0))
  517. assert intersection(l1, p1) == [p1]
  518. assert intersection(l1, Point3D(x1, 1 + x1, 1)) == []
  519. assert intersection(l1, l1.parallel_line(p1)) == [Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1))]
  520. assert intersection(l2, r2) == [r2]
  521. assert intersection(l2, s1) == [s1]
  522. assert intersection(r2, l2) == [r2]
  523. assert intersection(r1, Ray3D(Point3D(1, 1, 1), Point3D(-1, -1, -1))) == [Point3D(1, 1, 1)]
  524. assert intersection(r1, Segment3D(Point3D(0, 0, 0), Point3D(2, 2, 2))) == [
  525. Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))]
  526. assert intersection(Ray3D(Point3D(1, 0, 0), Point3D(-1, 0, 0)), Ray3D(Point3D(0, 1, 0), Point3D(0, -1, 0))) \
  527. == [Point3D(0, 0, 0)]
  528. assert intersection(r1, Ray3D(Point3D(2, 2, 2), Point3D(0, 0, 0))) == \
  529. [Segment3D(Point3D(1, 1, 1), Point3D(2, 2, 2))]
  530. assert intersection(s1, r2) == [s1]
  531. assert Line3D(Point3D(4, 0, 1), Point3D(0, 4, 1)).intersection(Line3D(Point3D(0, 0, 1), Point3D(4, 4, 1))) == \
  532. [Point3D(2, 2, 1)]
  533. assert Line3D((0, 1, 2), (0, 2, 3)).intersection(Line3D((0, 1, 2), (0, 1, 1))) == [Point3D(0, 1, 2)]
  534. assert Line3D((0, 0), (t, t)).intersection(Line3D((0, 1), (t, t))) == \
  535. [Point3D(t, t)]
  536. assert Ray3D(Point3D(0, 0, 0), Point3D(0, 4, 0)).intersection(Ray3D(Point3D(0, 1, 1), Point3D(0, -1, 1))) == []
  537. def test_is_parallel():
  538. p1 = Point3D(0, 0, 0)
  539. p2 = Point3D(1, 1, 1)
  540. p3 = Point3D(x1, x1, x1)
  541. l2 = Line(Point(x1, x1), Point(y1, y1))
  542. l2_1 = Line(Point(x1, x1), Point(x1, 1 + x1))
  543. assert Line.is_parallel(Line(Point(0, 0), Point(1, 1)), l2)
  544. assert Line.is_parallel(l2, Line(Point(x1, x1), Point(x1, 1 + x1))) is False
  545. assert Line.is_parallel(l2, l2.parallel_line(Point(-x1, x1)))
  546. assert Line.is_parallel(l2_1, l2_1.parallel_line(Point(0, 0)))
  547. assert Line3D(p1, p2).is_parallel(Line3D(p1, p2)) # same as in 2D
  548. assert Line3D(Point3D(4, 0, 1), Point3D(0, 4, 1)).is_parallel(Line3D(Point3D(0, 0, 1), Point3D(4, 4, 1))) is False
  549. assert Line3D(p1, p2).parallel_line(p3) == Line3D(Point3D(x1, x1, x1),
  550. Point3D(x1 + 1, x1 + 1, x1 + 1))
  551. assert Line3D(p1, p2).parallel_line(p3.args) == \
  552. Line3D(Point3D(x1, x1, x1), Point3D(x1 + 1, x1 + 1, x1 + 1))
  553. assert Line3D(Point3D(4, 0, 1), Point3D(0, 4, 1)).is_parallel(Line3D(Point3D(0, 0, 1), Point3D(4, 4, 1))) is False
  554. def test_is_perpendicular():
  555. p1 = Point(0, 0)
  556. p2 = Point(1, 1)
  557. l1 = Line(p1, p2)
  558. l2 = Line(Point(x1, x1), Point(y1, y1))
  559. l1_1 = Line(p1, Point(-x1, x1))
  560. # 2D
  561. assert Line.is_perpendicular(l1, l1_1)
  562. assert Line.is_perpendicular(l1, l2) is False
  563. p = l1.random_point()
  564. assert l1.perpendicular_segment(p) == p
  565. # 3D
  566. assert Line3D.is_perpendicular(Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)),
  567. Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))) is True
  568. assert Line3D.is_perpendicular(Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0)),
  569. Line3D(Point3D(0, 1, 0), Point3D(1, 1, 0))) is False
  570. assert Line3D.is_perpendicular(Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1)),
  571. Line3D(Point3D(x1, x1, x1), Point3D(y1, y1, y1))) is False
  572. def test_is_similar():
  573. p1 = Point(2000, 2000)
  574. p2 = p1.scale(2, 2)
  575. r1 = Ray3D(Point3D(1, 1, 1), Point3D(1, 0, 0))
  576. r2 = Ray(Point(0, 0), Point(0, 1))
  577. s1 = Segment(Point(0, 0), p1)
  578. assert s1.is_similar(Segment(p1, p2))
  579. assert s1.is_similar(r2) is False
  580. assert r1.is_similar(Line3D(Point3D(1, 1, 1), Point3D(1, 0, 0))) is True
  581. assert r1.is_similar(Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))) is False
  582. def test_length():
  583. s2 = Segment3D(Point3D(x1, x1, x1), Point3D(y1, y1, y1))
  584. assert Line(Point(0, 0), Point(1, 1)).length is oo
  585. assert s2.length == sqrt(3) * sqrt((x1 - y1) ** 2)
  586. assert Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1)).length is oo
  587. def test_projection():
  588. p1 = Point(0, 0)
  589. p2 = Point3D(0, 0, 0)
  590. p3 = Point(-x1, x1)
  591. l1 = Line(p1, Point(1, 1))
  592. l2 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))
  593. l3 = Line3D(p2, Point3D(1, 1, 1))
  594. r1 = Ray(Point(1, 1), Point(2, 2))
  595. s1 = Segment(Point2D(0, 0), Point2D(0, 1))
  596. s2 = Segment(Point2D(1, 0), Point2D(2, 1/2))
  597. assert Line(Point(x1, x1), Point(y1, y1)).projection(Point(y1, y1)) == Point(y1, y1)
  598. assert Line(Point(x1, x1), Point(x1, 1 + x1)).projection(Point(1, 1)) == Point(x1, 1)
  599. assert Segment(Point(-2, 2), Point(0, 4)).projection(r1) == Segment(Point(-1, 3), Point(0, 4))
  600. assert Segment(Point(0, 4), Point(-2, 2)).projection(r1) == Segment(Point(0, 4), Point(-1, 3))
  601. assert s2.projection(s1) == EmptySet
  602. assert l1.projection(p3) == p1
  603. assert l1.projection(Ray(p1, Point(-1, 5))) == Ray(Point(0, 0), Point(2, 2))
  604. assert l1.projection(Ray(p1, Point(-1, 1))) == p1
  605. assert r1.projection(Ray(Point(1, 1), Point(-1, -1))) == Point(1, 1)
  606. assert r1.projection(Ray(Point(0, 4), Point(-1, -5))) == Segment(Point(1, 1), Point(2, 2))
  607. assert r1.projection(Segment(Point(-1, 5), Point(-5, -10))) == Segment(Point(1, 1), Point(2, 2))
  608. assert r1.projection(Ray(Point(1, 1), Point(-1, -1))) == Point(1, 1)
  609. assert r1.projection(Ray(Point(0, 4), Point(-1, -5))) == Segment(Point(1, 1), Point(2, 2))
  610. assert r1.projection(Segment(Point(-1, 5), Point(-5, -10))) == Segment(Point(1, 1), Point(2, 2))
  611. assert l3.projection(Ray3D(p2, Point3D(-1, 5, 0))) == Ray3D(Point3D(0, 0, 0), Point3D(Rational(4, 3), Rational(4, 3), Rational(4, 3)))
  612. assert l3.projection(Ray3D(p2, Point3D(-1, 1, 1))) == Ray3D(Point3D(0, 0, 0), Point3D(Rational(1, 3), Rational(1, 3), Rational(1, 3)))
  613. assert l2.projection(Point3D(5, 5, 0)) == Point3D(5, 0)
  614. assert l2.projection(Line3D(Point3D(0, 1, 0), Point3D(1, 1, 0))).equals(l2)
  615. def test_perpendicular_bisector():
  616. s1 = Segment(Point(0, 0), Point(1, 1))
  617. aline = Line(Point(S.Half, S.Half), Point(Rational(3, 2), Rational(-1, 2)))
  618. on_line = Segment(Point(S.Half, S.Half), Point(Rational(3, 2), Rational(-1, 2))).midpoint
  619. assert s1.perpendicular_bisector().equals(aline)
  620. assert s1.perpendicular_bisector(on_line).equals(Segment(s1.midpoint, on_line))
  621. assert s1.perpendicular_bisector(on_line + (1, 0)).equals(aline)
  622. def test_raises():
  623. d, e = symbols('a,b', real=True)
  624. s = Segment((d, 0), (e, 0))
  625. raises(TypeError, lambda: Line((1, 1), 1))
  626. raises(ValueError, lambda: Line(Point(0, 0), Point(0, 0)))
  627. raises(Undecidable, lambda: Point(2 * d, 0) in s)
  628. raises(ValueError, lambda: Ray3D(Point(1.0, 1.0)))
  629. raises(ValueError, lambda: Line3D(Point3D(0, 0, 0), Point3D(0, 0, 0)))
  630. raises(TypeError, lambda: Line3D((1, 1), 1))
  631. raises(ValueError, lambda: Line3D(Point3D(0, 0, 0)))
  632. raises(TypeError, lambda: Ray((1, 1), 1))
  633. raises(GeometryError, lambda: Line(Point(0, 0), Point(1, 0))
  634. .projection(Circle(Point(0, 0), 1)))
  635. def test_ray_generation():
  636. assert Ray((1, 1), angle=pi / 4) == Ray((1, 1), (2, 2))
  637. assert Ray((1, 1), angle=pi / 2) == Ray((1, 1), (1, 2))
  638. assert Ray((1, 1), angle=-pi / 2) == Ray((1, 1), (1, 0))
  639. assert Ray((1, 1), angle=-3 * pi / 2) == Ray((1, 1), (1, 2))
  640. assert Ray((1, 1), angle=5 * pi / 2) == Ray((1, 1), (1, 2))
  641. assert Ray((1, 1), angle=5.0 * pi / 2) == Ray((1, 1), (1, 2))
  642. assert Ray((1, 1), angle=pi) == Ray((1, 1), (0, 1))
  643. assert Ray((1, 1), angle=3.0 * pi) == Ray((1, 1), (0, 1))
  644. assert Ray((1, 1), angle=4.0 * pi) == Ray((1, 1), (2, 1))
  645. assert Ray((1, 1), angle=0) == Ray((1, 1), (2, 1))
  646. assert Ray((1, 1), angle=4.05 * pi) == Ray(Point(1, 1),
  647. Point(2, -sqrt(5) * sqrt(2 * sqrt(5) + 10) / 4 - sqrt(
  648. 2 * sqrt(5) + 10) / 4 + 2 + sqrt(5)))
  649. assert Ray((1, 1), angle=4.02 * pi) == Ray(Point(1, 1),
  650. Point(2, 1 + tan(4.02 * pi)))
  651. assert Ray((1, 1), angle=5) == Ray((1, 1), (2, 1 + tan(5)))
  652. assert Ray3D((1, 1, 1), direction_ratio=[4, 4, 4]) == Ray3D(Point3D(1, 1, 1), Point3D(5, 5, 5))
  653. assert Ray3D((1, 1, 1), direction_ratio=[1, 2, 3]) == Ray3D(Point3D(1, 1, 1), Point3D(2, 3, 4))
  654. assert Ray3D((1, 1, 1), direction_ratio=[1, 1, 1]) == Ray3D(Point3D(1, 1, 1), Point3D(2, 2, 2))
  655. def test_symbolic_intersect():
  656. # Issue 7814.
  657. circle = Circle(Point(x, 0), y)
  658. line = Line(Point(k, z), slope=0)
  659. assert line.intersection(circle) == [Point(x + sqrt((y - z) * (y + z)), z), Point(x - sqrt((y - z) * (y + z)), z)]
  660. def test_issue_2941():
  661. def _check():
  662. for f, g in cartes(*[(Line, Ray, Segment)] * 2):
  663. l1 = f(a, b)
  664. l2 = g(c, d)
  665. assert l1.intersection(l2) == l2.intersection(l1)
  666. # intersect at end point
  667. c, d = (-2, -2), (-2, 0)
  668. a, b = (0, 0), (1, 1)
  669. _check()
  670. # midline intersection
  671. c, d = (-2, -3), (-2, 0)
  672. _check()
  673. def test_parameter_value():
  674. t = Symbol('t')
  675. p1, p2 = Point(0, 1), Point(5, 6)
  676. l = Line(p1, p2)
  677. assert l.parameter_value((5, 6), t) == {t: 1}
  678. raises(ValueError, lambda: l.parameter_value((0, 0), t))
  679. def test_bisectors():
  680. r1 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))
  681. r2 = Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))
  682. bisections = r1.bisectors(r2)
  683. assert bisections == [Line3D(Point3D(0, 0, 0), Point3D(1, 1, 0)),
  684. Line3D(Point3D(0, 0, 0), Point3D(1, -1, 0))]
  685. ans = [Line3D(Point3D(0, 0, 0), Point3D(1, 0, 1)),
  686. Line3D(Point3D(0, 0, 0), Point3D(-1, 0, 1))]
  687. l1 = (0, 0, 0), (0, 0, 1)
  688. l2 = (0, 0), (1, 0)
  689. for a, b in cartes((Line, Segment, Ray), repeat=2):
  690. assert a(*l1).bisectors(b(*l2)) == ans
  691. def test_issue_8615():
  692. a = Line3D(Point3D(6, 5, 0), Point3D(6, -6, 0))
  693. b = Line3D(Point3D(6, -1, 19/10), Point3D(6, -1, 0))
  694. assert a.intersection(b) == [Point3D(6, -1, 0)]