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

1"""Parabolic geometrical entity. 

2 

3Contains 

4* Parabola 

5 

6""" 

7 

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 

18 

19 

20class Parabola(GeometrySet): 

21 """A parabolic GeometryEntity. 

22 

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. 

26 

27 Parameters 

28 ========== 

29 

30 focus : Point 

31 Default value is Point(0, 0) 

32 directrix : Line 

33 

34 Attributes 

35 ========== 

36 

37 focus 

38 directrix 

39 axis of symmetry 

40 focal length 

41 p parameter 

42 vertex 

43 eccentricity 

44 

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. 

52 

53 Examples 

54 ======== 

55 

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)) 

62 

63 """ 

64 

65 def __new__(cls, focus=None, directrix=None, **kwargs): 

66 

67 if focus: 

68 focus = Point(focus, dim=2) 

69 else: 

70 focus = Point(0, 0) 

71 

72 directrix = Line(directrix) 

73 

74 if directrix.contains(focus): 

75 raise ValueError('The focus must not be a point of directrix') 

76 

77 return GeometryEntity.__new__(cls, focus, directrix, **kwargs) 

78 

79 @property 

80 def ambient_dimension(self): 

81 """Returns the ambient dimension of parabola. 

82 

83 Returns 

84 ======= 

85 

86 ambient_dimension : integer 

87 

88 Examples 

89 ======== 

90 

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 

96 

97 """ 

98 return 2 

99 

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. 

104 

105 Returns 

106 ======= 

107 

108 axis_of_symmetry : Line 

109 

110 See Also 

111 ======== 

112 

113 sympy.geometry.line.Line 

114 

115 Examples 

116 ======== 

117 

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)) 

122 

123 """ 

124 return self.directrix.perpendicular_line(self.focus) 

125 

126 @property 

127 def directrix(self): 

128 """The directrix of the parabola. 

129 

130 Returns 

131 ======= 

132 

133 directrix : Line 

134 

135 See Also 

136 ======== 

137 

138 sympy.geometry.line.Line 

139 

140 Examples 

141 ======== 

142 

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)) 

148 

149 """ 

150 return self.args[1] 

151 

152 @property 

153 def eccentricity(self): 

154 """The eccentricity of the parabola. 

155 

156 Returns 

157 ======= 

158 

159 eccentricity : number 

160 

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. 

165 

166 See Also 

167 ======== 

168 

169 https://en.wikipedia.org/wiki/Parabola 

170 

171 

172 Examples 

173 ======== 

174 

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 

179 

180 Notes 

181 ----- 

182 The eccentricity for every Parabola is 1 by definition. 

183 

184 """ 

185 return S.One 

186 

187 def equation(self, x='x', y='y'): 

188 """The equation of the parabola. 

189 

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'. 

196 

197 Returns 

198 ======= 

199 equation : SymPy expression 

200 

201 Examples 

202 ======== 

203 

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 

212 

213 """ 

214 x = _symbol(x, real=True) 

215 y = _symbol(y, real=True) 

216 

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 

230 

231 @property 

232 def focal_length(self): 

233 """The focal length of the parabola. 

234 

235 Returns 

236 ======= 

237 

238 focal_lenght : number or symbolic expression 

239 

240 Notes 

241 ===== 

242 

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". 

246 

247 See Also 

248 ======== 

249 

250 https://en.wikipedia.org/wiki/Parabola 

251 

252 Examples 

253 ======== 

254 

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 

259 

260 """ 

261 distance = self.directrix.distance(self.focus) 

262 focal_length = distance/2 

263 

264 return focal_length 

265 

266 @property 

267 def focus(self): 

268 """The focus of the parabola. 

269 

270 Returns 

271 ======= 

272 

273 focus : Point 

274 

275 See Also 

276 ======== 

277 

278 sympy.geometry.point.Point 

279 

280 Examples 

281 ======== 

282 

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) 

288 

289 """ 

290 return self.args[0] 

291 

292 def intersection(self, o): 

293 """The intersection of the parabola and another geometrical entity `o`. 

294 

295 Parameters 

296 ========== 

297 

298 o : GeometryEntity, LinearEntity 

299 

300 Returns 

301 ======= 

302 

303 intersection : list of GeometryEntity objects 

304 

305 Examples 

306 ======== 

307 

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 [] 

318 

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') 

345 

346 @property 

347 def p_parameter(self): 

348 """P is a parameter of parabola. 

349 

350 Returns 

351 ======= 

352 

353 p : number or symbolic expression 

354 

355 Notes 

356 ===== 

357 

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. 

363 

364 

365 See Also 

366 ======== 

367 

368 https://www.sparknotes.com/math/precalc/conicsections/section2/ 

369 

370 Examples 

371 ======== 

372 

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 

377 

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 

390 

391 @property 

392 def vertex(self): 

393 """The vertex of the parabola. 

394 

395 Returns 

396 ======= 

397 

398 vertex : Point 

399 

400 See Also 

401 ======== 

402 

403 sympy.geometry.point.Point 

404 

405 Examples 

406 ======== 

407 

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) 

412 

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