Coverage for /usr/lib/python3/dist-packages/sympy/geometry/parabola.py: 32%
95 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1"""Parabolic geometrical entity.
3Contains
4* Parabola
6"""
8from sympy.core import S
9from sympy.core.sorting import ordered
10from sympy.core.symbol import _symbol, symbols
11from sympy.geometry.entity import GeometryEntity, GeometrySet
12from sympy.geometry.point import Point, Point2D
13from sympy.geometry.line import Line, Line2D, Ray2D, Segment2D, LinearEntity3D
14from sympy.geometry.ellipse import Ellipse
15from sympy.functions import sign
16from sympy.simplify import simplify
17from sympy.solvers.solvers import solve
20class Parabola(GeometrySet):
21 """A parabolic GeometryEntity.
23 A parabola is declared with a point, that is called 'focus', and
24 a line, that is called 'directrix'.
25 Only vertical or horizontal parabolas are currently supported.
27 Parameters
28 ==========
30 focus : Point
31 Default value is Point(0, 0)
32 directrix : Line
34 Attributes
35 ==========
37 focus
38 directrix
39 axis of symmetry
40 focal length
41 p parameter
42 vertex
43 eccentricity
45 Raises
46 ======
47 ValueError
48 When `focus` is not a two dimensional point.
49 When `focus` is a point of directrix.
50 NotImplementedError
51 When `directrix` is neither horizontal nor vertical.
53 Examples
54 ========
56 >>> from sympy import Parabola, Point, Line
57 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7,8)))
58 >>> p1.focus
59 Point2D(0, 0)
60 >>> p1.directrix
61 Line2D(Point2D(5, 8), Point2D(7, 8))
63 """
65 def __new__(cls, focus=None, directrix=None, **kwargs):
67 if focus:
68 focus = Point(focus, dim=2)
69 else:
70 focus = Point(0, 0)
72 directrix = Line(directrix)
74 if directrix.contains(focus):
75 raise ValueError('The focus must not be a point of directrix')
77 return GeometryEntity.__new__(cls, focus, directrix, **kwargs)
79 @property
80 def ambient_dimension(self):
81 """Returns the ambient dimension of parabola.
83 Returns
84 =======
86 ambient_dimension : integer
88 Examples
89 ========
91 >>> from sympy import Parabola, Point, Line
92 >>> f1 = Point(0, 0)
93 >>> p1 = Parabola(f1, Line(Point(5, 8), Point(7, 8)))
94 >>> p1.ambient_dimension
95 2
97 """
98 return 2
100 @property
101 def axis_of_symmetry(self):
102 """Return the axis of symmetry of the parabola: a line
103 perpendicular to the directrix passing through the focus.
105 Returns
106 =======
108 axis_of_symmetry : Line
110 See Also
111 ========
113 sympy.geometry.line.Line
115 Examples
116 ========
118 >>> from sympy import Parabola, Point, Line
119 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8)))
120 >>> p1.axis_of_symmetry
121 Line2D(Point2D(0, 0), Point2D(0, 1))
123 """
124 return self.directrix.perpendicular_line(self.focus)
126 @property
127 def directrix(self):
128 """The directrix of the parabola.
130 Returns
131 =======
133 directrix : Line
135 See Also
136 ========
138 sympy.geometry.line.Line
140 Examples
141 ========
143 >>> from sympy import Parabola, Point, Line
144 >>> l1 = Line(Point(5, 8), Point(7, 8))
145 >>> p1 = Parabola(Point(0, 0), l1)
146 >>> p1.directrix
147 Line2D(Point2D(5, 8), Point2D(7, 8))
149 """
150 return self.args[1]
152 @property
153 def eccentricity(self):
154 """The eccentricity of the parabola.
156 Returns
157 =======
159 eccentricity : number
161 A parabola may also be characterized as a conic section with an
162 eccentricity of 1. As a consequence of this, all parabolas are
163 similar, meaning that while they can be different sizes,
164 they are all the same shape.
166 See Also
167 ========
169 https://en.wikipedia.org/wiki/Parabola
172 Examples
173 ========
175 >>> from sympy import Parabola, Point, Line
176 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8)))
177 >>> p1.eccentricity
178 1
180 Notes
181 -----
182 The eccentricity for every Parabola is 1 by definition.
184 """
185 return S.One
187 def equation(self, x='x', y='y'):
188 """The equation of the parabola.
190 Parameters
191 ==========
192 x : str, optional
193 Label for the x-axis. Default value is 'x'.
194 y : str, optional
195 Label for the y-axis. Default value is 'y'.
197 Returns
198 =======
199 equation : SymPy expression
201 Examples
202 ========
204 >>> from sympy import Parabola, Point, Line
205 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8)))
206 >>> p1.equation()
207 -x**2 - 16*y + 64
208 >>> p1.equation('f')
209 -f**2 - 16*y + 64
210 >>> p1.equation(y='z')
211 -x**2 - 16*z + 64
213 """
214 x = _symbol(x, real=True)
215 y = _symbol(y, real=True)
217 m = self.directrix.slope
218 if m is S.Infinity:
219 t1 = 4 * (self.p_parameter) * (x - self.vertex.x)
220 t2 = (y - self.vertex.y)**2
221 elif m == 0:
222 t1 = 4 * (self.p_parameter) * (y - self.vertex.y)
223 t2 = (x - self.vertex.x)**2
224 else:
225 a, b = self.focus
226 c, d = self.directrix.coefficients[:2]
227 t1 = (x - a)**2 + (y - b)**2
228 t2 = self.directrix.equation(x, y)**2/(c**2 + d**2)
229 return t1 - t2
231 @property
232 def focal_length(self):
233 """The focal length of the parabola.
235 Returns
236 =======
238 focal_lenght : number or symbolic expression
240 Notes
241 =====
243 The distance between the vertex and the focus
244 (or the vertex and directrix), measured along the axis
245 of symmetry, is the "focal length".
247 See Also
248 ========
250 https://en.wikipedia.org/wiki/Parabola
252 Examples
253 ========
255 >>> from sympy import Parabola, Point, Line
256 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8)))
257 >>> p1.focal_length
258 4
260 """
261 distance = self.directrix.distance(self.focus)
262 focal_length = distance/2
264 return focal_length
266 @property
267 def focus(self):
268 """The focus of the parabola.
270 Returns
271 =======
273 focus : Point
275 See Also
276 ========
278 sympy.geometry.point.Point
280 Examples
281 ========
283 >>> from sympy import Parabola, Point, Line
284 >>> f1 = Point(0, 0)
285 >>> p1 = Parabola(f1, Line(Point(5, 8), Point(7, 8)))
286 >>> p1.focus
287 Point2D(0, 0)
289 """
290 return self.args[0]
292 def intersection(self, o):
293 """The intersection of the parabola and another geometrical entity `o`.
295 Parameters
296 ==========
298 o : GeometryEntity, LinearEntity
300 Returns
301 =======
303 intersection : list of GeometryEntity objects
305 Examples
306 ========
308 >>> from sympy import Parabola, Point, Ellipse, Line, Segment
309 >>> p1 = Point(0,0)
310 >>> l1 = Line(Point(1, -2), Point(-1,-2))
311 >>> parabola1 = Parabola(p1, l1)
312 >>> parabola1.intersection(Ellipse(Point(0, 0), 2, 5))
313 [Point2D(-2, 0), Point2D(2, 0)]
314 >>> parabola1.intersection(Line(Point(-7, 3), Point(12, 3)))
315 [Point2D(-4, 3), Point2D(4, 3)]
316 >>> parabola1.intersection(Segment((-12, -65), (14, -68)))
317 []
319 """
320 x, y = symbols('x y', real=True)
321 parabola_eq = self.equation()
322 if isinstance(o, Parabola):
323 if o in self:
324 return [o]
325 else:
326 return list(ordered([Point(i) for i in solve(
327 [parabola_eq, o.equation()], [x, y], set=True)[1]]))
328 elif isinstance(o, Point2D):
329 if simplify(parabola_eq.subs([(x, o._args[0]), (y, o._args[1])])) == 0:
330 return [o]
331 else:
332 return []
333 elif isinstance(o, (Segment2D, Ray2D)):
334 result = solve([parabola_eq,
335 Line2D(o.points[0], o.points[1]).equation()],
336 [x, y], set=True)[1]
337 return list(ordered([Point2D(i) for i in result if i in o]))
338 elif isinstance(o, (Line2D, Ellipse)):
339 return list(ordered([Point2D(i) for i in solve(
340 [parabola_eq, o.equation()], [x, y], set=True)[1]]))
341 elif isinstance(o, LinearEntity3D):
342 raise TypeError('Entity must be two dimensional, not three dimensional')
343 else:
344 raise TypeError('Wrong type of argument were put')
346 @property
347 def p_parameter(self):
348 """P is a parameter of parabola.
350 Returns
351 =======
353 p : number or symbolic expression
355 Notes
356 =====
358 The absolute value of p is the focal length. The sign on p tells
359 which way the parabola faces. Vertical parabolas that open up
360 and horizontal that open right, give a positive value for p.
361 Vertical parabolas that open down and horizontal that open left,
362 give a negative value for p.
365 See Also
366 ========
368 https://www.sparknotes.com/math/precalc/conicsections/section2/
370 Examples
371 ========
373 >>> from sympy import Parabola, Point, Line
374 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8)))
375 >>> p1.p_parameter
376 -4
378 """
379 m = self.directrix.slope
380 if m is S.Infinity:
381 x = self.directrix.coefficients[2]
382 p = sign(self.focus.args[0] + x)
383 elif m == 0:
384 y = self.directrix.coefficients[2]
385 p = sign(self.focus.args[1] + y)
386 else:
387 d = self.directrix.projection(self.focus)
388 p = sign(self.focus.x - d.x)
389 return p * self.focal_length
391 @property
392 def vertex(self):
393 """The vertex of the parabola.
395 Returns
396 =======
398 vertex : Point
400 See Also
401 ========
403 sympy.geometry.point.Point
405 Examples
406 ========
408 >>> from sympy import Parabola, Point, Line
409 >>> p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7, 8)))
410 >>> p1.vertex
411 Point2D(0, 4)
413 """
414 focus = self.focus
415 m = self.directrix.slope
416 if m is S.Infinity:
417 vertex = Point(focus.args[0] - self.p_parameter, focus.args[1])
418 elif m == 0:
419 vertex = Point(focus.args[0], focus.args[1] - self.p_parameter)
420 else:
421 vertex = self.axis_of_symmetry.intersection(self)[0]
422 return vertex