body.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. from sympy import Symbol
  2. from sympy.physics.vector import Point, Vector, ReferenceFrame, Dyadic
  3. from sympy.physics.mechanics import RigidBody, Particle, Inertia
  4. from sympy.physics.mechanics.body_base import BodyBase
  5. from sympy.utilities.exceptions import sympy_deprecation_warning
  6. __all__ = ['Body']
  7. # XXX: We use type:ignore because the classes RigidBody and Particle have
  8. # inconsistent parallel axis methods that take different numbers of arguments.
  9. class Body(RigidBody, Particle): # type: ignore
  10. """
  11. Body is a common representation of either a RigidBody or a Particle SymPy
  12. object depending on what is passed in during initialization. If a mass is
  13. passed in and central_inertia is left as None, the Particle object is
  14. created. Otherwise a RigidBody object will be created.
  15. .. deprecated:: 1.13
  16. The Body class is deprecated. Its functionality is captured by
  17. :class:`~.RigidBody` and :class:`~.Particle`.
  18. Explanation
  19. ===========
  20. The attributes that Body possesses will be the same as a Particle instance
  21. or a Rigid Body instance depending on which was created. Additional
  22. attributes are listed below.
  23. Attributes
  24. ==========
  25. name : string
  26. The body's name
  27. masscenter : Point
  28. The point which represents the center of mass of the rigid body
  29. frame : ReferenceFrame
  30. The reference frame which the body is fixed in
  31. mass : Sympifyable
  32. The body's mass
  33. inertia : (Dyadic, Point)
  34. The body's inertia around its center of mass. This attribute is specific
  35. to the rigid body form of Body and is left undefined for the Particle
  36. form
  37. loads : iterable
  38. This list contains information on the different loads acting on the
  39. Body. Forces are listed as a (point, vector) tuple and torques are
  40. listed as (reference frame, vector) tuples.
  41. Parameters
  42. ==========
  43. name : String
  44. Defines the name of the body. It is used as the base for defining
  45. body specific properties.
  46. masscenter : Point, optional
  47. A point that represents the center of mass of the body or particle.
  48. If no point is given, a point is generated.
  49. mass : Sympifyable, optional
  50. A Sympifyable object which represents the mass of the body. If no
  51. mass is passed, one is generated.
  52. frame : ReferenceFrame, optional
  53. The ReferenceFrame that represents the reference frame of the body.
  54. If no frame is given, a frame is generated.
  55. central_inertia : Dyadic, optional
  56. Central inertia dyadic of the body. If none is passed while creating
  57. RigidBody, a default inertia is generated.
  58. Examples
  59. ========
  60. As Body has been deprecated, the following examples are for illustrative
  61. purposes only. The functionality of Body is fully captured by
  62. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  63. warning we can use the ignore_warnings context manager.
  64. >>> from sympy.utilities.exceptions import ignore_warnings
  65. Default behaviour. This results in the creation of a RigidBody object for
  66. which the mass, mass center, frame and inertia attributes are given default
  67. values. ::
  68. >>> from sympy.physics.mechanics import Body
  69. >>> with ignore_warnings(DeprecationWarning):
  70. ... body = Body('name_of_body')
  71. This next example demonstrates the code required to specify all of the
  72. values of the Body object. Note this will also create a RigidBody version of
  73. the Body object. ::
  74. >>> from sympy import Symbol
  75. >>> from sympy.physics.mechanics import ReferenceFrame, Point, inertia
  76. >>> from sympy.physics.mechanics import Body
  77. >>> mass = Symbol('mass')
  78. >>> masscenter = Point('masscenter')
  79. >>> frame = ReferenceFrame('frame')
  80. >>> ixx = Symbol('ixx')
  81. >>> body_inertia = inertia(frame, ixx, 0, 0)
  82. >>> with ignore_warnings(DeprecationWarning):
  83. ... body = Body('name_of_body', masscenter, mass, frame, body_inertia)
  84. The minimal code required to create a Particle version of the Body object
  85. involves simply passing in a name and a mass. ::
  86. >>> from sympy import Symbol
  87. >>> from sympy.physics.mechanics import Body
  88. >>> mass = Symbol('mass')
  89. >>> with ignore_warnings(DeprecationWarning):
  90. ... body = Body('name_of_body', mass=mass)
  91. The Particle version of the Body object can also receive a masscenter point
  92. and a reference frame, just not an inertia.
  93. """
  94. def __init__(self, name, masscenter=None, mass=None, frame=None,
  95. central_inertia=None):
  96. sympy_deprecation_warning(
  97. """
  98. Support for the Body class has been removed, as its functionality is
  99. fully captured by RigidBody and Particle.
  100. """,
  101. deprecated_since_version="1.13",
  102. active_deprecations_target="deprecated-mechanics-body-class"
  103. )
  104. self._loads = []
  105. if frame is None:
  106. frame = ReferenceFrame(name + '_frame')
  107. if masscenter is None:
  108. masscenter = Point(name + '_masscenter')
  109. if central_inertia is None and mass is None:
  110. ixx = Symbol(name + '_ixx')
  111. iyy = Symbol(name + '_iyy')
  112. izz = Symbol(name + '_izz')
  113. izx = Symbol(name + '_izx')
  114. ixy = Symbol(name + '_ixy')
  115. iyz = Symbol(name + '_iyz')
  116. _inertia = Inertia.from_inertia_scalars(masscenter, frame, ixx, iyy,
  117. izz, ixy, iyz, izx)
  118. else:
  119. _inertia = (central_inertia, masscenter)
  120. if mass is None:
  121. _mass = Symbol(name + '_mass')
  122. else:
  123. _mass = mass
  124. masscenter.set_vel(frame, 0)
  125. # If user passes masscenter and mass then a particle is created
  126. # otherwise a rigidbody. As a result a body may or may not have inertia.
  127. # Note: BodyBase.__init__ is used to prevent problems with super() calls in
  128. # Particle and RigidBody arising due to multiple inheritance.
  129. if central_inertia is None and mass is not None:
  130. BodyBase.__init__(self, name, masscenter, _mass)
  131. self.frame = frame
  132. self._central_inertia = Dyadic(0)
  133. else:
  134. BodyBase.__init__(self, name, masscenter, _mass)
  135. self.frame = frame
  136. self.inertia = _inertia
  137. def __repr__(self):
  138. if self.is_rigidbody:
  139. return RigidBody.__repr__(self)
  140. return Particle.__repr__(self)
  141. @property
  142. def loads(self):
  143. return self._loads
  144. @property
  145. def x(self):
  146. """The basis Vector for the Body, in the x direction."""
  147. return self.frame.x
  148. @property
  149. def y(self):
  150. """The basis Vector for the Body, in the y direction."""
  151. return self.frame.y
  152. @property
  153. def z(self):
  154. """The basis Vector for the Body, in the z direction."""
  155. return self.frame.z
  156. @property
  157. def inertia(self):
  158. """The body's inertia about a point; stored as (Dyadic, Point)."""
  159. if self.is_rigidbody:
  160. return RigidBody.inertia.fget(self)
  161. return (self.central_inertia, self.masscenter)
  162. @inertia.setter
  163. def inertia(self, I):
  164. RigidBody.inertia.fset(self, I)
  165. @property
  166. def is_rigidbody(self):
  167. if hasattr(self, '_inertia'):
  168. return True
  169. return False
  170. def kinetic_energy(self, frame):
  171. """Kinetic energy of the body.
  172. Parameters
  173. ==========
  174. frame : ReferenceFrame or Body
  175. The Body's angular velocity and the velocity of it's mass
  176. center are typically defined with respect to an inertial frame but
  177. any relevant frame in which the velocities are known can be supplied.
  178. Examples
  179. ========
  180. As Body has been deprecated, the following examples are for illustrative
  181. purposes only. The functionality of Body is fully captured by
  182. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  183. warning we can use the ignore_warnings context manager.
  184. >>> from sympy.utilities.exceptions import ignore_warnings
  185. >>> from sympy.physics.mechanics import Body, ReferenceFrame, Point
  186. >>> from sympy import symbols
  187. >>> m, v, r, omega = symbols('m v r omega')
  188. >>> N = ReferenceFrame('N')
  189. >>> O = Point('O')
  190. >>> with ignore_warnings(DeprecationWarning):
  191. ... P = Body('P', masscenter=O, mass=m)
  192. >>> P.masscenter.set_vel(N, v * N.y)
  193. >>> P.kinetic_energy(N)
  194. m*v**2/2
  195. >>> N = ReferenceFrame('N')
  196. >>> b = ReferenceFrame('b')
  197. >>> b.set_ang_vel(N, omega * b.x)
  198. >>> P = Point('P')
  199. >>> P.set_vel(N, v * N.x)
  200. >>> with ignore_warnings(DeprecationWarning):
  201. ... B = Body('B', masscenter=P, frame=b)
  202. >>> B.kinetic_energy(N)
  203. B_ixx*omega**2/2 + B_mass*v**2/2
  204. See Also
  205. ========
  206. sympy.physics.mechanics : Particle, RigidBody
  207. """
  208. if isinstance(frame, Body):
  209. frame = Body.frame
  210. if self.is_rigidbody:
  211. return RigidBody(self.name, self.masscenter, self.frame, self.mass,
  212. (self.central_inertia, self.masscenter)).kinetic_energy(frame)
  213. return Particle(self.name, self.masscenter, self.mass).kinetic_energy(frame)
  214. def apply_force(self, force, point=None, reaction_body=None, reaction_point=None):
  215. """Add force to the body(s).
  216. Explanation
  217. ===========
  218. Applies the force on self or equal and opposite forces on
  219. self and other body if both are given on the desired point on the bodies.
  220. The force applied on other body is taken opposite of self, i.e, -force.
  221. Parameters
  222. ==========
  223. force: Vector
  224. The force to be applied.
  225. point: Point, optional
  226. The point on self on which force is applied.
  227. By default self's masscenter.
  228. reaction_body: Body, optional
  229. Second body on which equal and opposite force
  230. is to be applied.
  231. reaction_point : Point, optional
  232. The point on other body on which equal and opposite
  233. force is applied. By default masscenter of other body.
  234. Example
  235. =======
  236. As Body has been deprecated, the following examples are for illustrative
  237. purposes only. The functionality of Body is fully captured by
  238. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  239. warning we can use the ignore_warnings context manager.
  240. >>> from sympy.utilities.exceptions import ignore_warnings
  241. >>> from sympy import symbols
  242. >>> from sympy.physics.mechanics import Body, Point, dynamicsymbols
  243. >>> m, g = symbols('m g')
  244. >>> with ignore_warnings(DeprecationWarning):
  245. ... B = Body('B')
  246. >>> force1 = m*g*B.z
  247. >>> B.apply_force(force1) #Applying force on B's masscenter
  248. >>> B.loads
  249. [(B_masscenter, g*m*B_frame.z)]
  250. We can also remove some part of force from any point on the body by
  251. adding the opposite force to the body on that point.
  252. >>> f1, f2 = dynamicsymbols('f1 f2')
  253. >>> P = Point('P') #Considering point P on body B
  254. >>> B.apply_force(f1*B.x + f2*B.y, P)
  255. >>> B.loads
  256. [(B_masscenter, g*m*B_frame.z), (P, f1(t)*B_frame.x + f2(t)*B_frame.y)]
  257. Let's remove f1 from point P on body B.
  258. >>> B.apply_force(-f1*B.x, P)
  259. >>> B.loads
  260. [(B_masscenter, g*m*B_frame.z), (P, f2(t)*B_frame.y)]
  261. To further demonstrate the use of ``apply_force`` attribute,
  262. consider two bodies connected through a spring.
  263. >>> from sympy.physics.mechanics import Body, dynamicsymbols
  264. >>> with ignore_warnings(DeprecationWarning):
  265. ... N = Body('N') #Newtonion Frame
  266. >>> x = dynamicsymbols('x')
  267. >>> with ignore_warnings(DeprecationWarning):
  268. ... B1 = Body('B1')
  269. ... B2 = Body('B2')
  270. >>> spring_force = x*N.x
  271. Now let's apply equal and opposite spring force to the bodies.
  272. >>> P1 = Point('P1')
  273. >>> P2 = Point('P2')
  274. >>> B1.apply_force(spring_force, point=P1, reaction_body=B2, reaction_point=P2)
  275. We can check the loads(forces) applied to bodies now.
  276. >>> B1.loads
  277. [(P1, x(t)*N_frame.x)]
  278. >>> B2.loads
  279. [(P2, - x(t)*N_frame.x)]
  280. Notes
  281. =====
  282. If a new force is applied to a body on a point which already has some
  283. force applied on it, then the new force is added to the already applied
  284. force on that point.
  285. """
  286. if not isinstance(point, Point):
  287. if point is None:
  288. point = self.masscenter # masscenter
  289. else:
  290. raise TypeError("Force must be applied to a point on the body.")
  291. if not isinstance(force, Vector):
  292. raise TypeError("Force must be a vector.")
  293. if reaction_body is not None:
  294. reaction_body.apply_force(-force, point=reaction_point)
  295. for load in self._loads:
  296. if point in load:
  297. force += load[1]
  298. self._loads.remove(load)
  299. break
  300. self._loads.append((point, force))
  301. def apply_torque(self, torque, reaction_body=None):
  302. """Add torque to the body(s).
  303. Explanation
  304. ===========
  305. Applies the torque on self or equal and opposite torques on
  306. self and other body if both are given.
  307. The torque applied on other body is taken opposite of self,
  308. i.e, -torque.
  309. Parameters
  310. ==========
  311. torque: Vector
  312. The torque to be applied.
  313. reaction_body: Body, optional
  314. Second body on which equal and opposite torque
  315. is to be applied.
  316. Example
  317. =======
  318. As Body has been deprecated, the following examples are for illustrative
  319. purposes only. The functionality of Body is fully captured by
  320. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  321. warning we can use the ignore_warnings context manager.
  322. >>> from sympy.utilities.exceptions import ignore_warnings
  323. >>> from sympy import symbols
  324. >>> from sympy.physics.mechanics import Body, dynamicsymbols
  325. >>> t = symbols('t')
  326. >>> with ignore_warnings(DeprecationWarning):
  327. ... B = Body('B')
  328. >>> torque1 = t*B.z
  329. >>> B.apply_torque(torque1)
  330. >>> B.loads
  331. [(B_frame, t*B_frame.z)]
  332. We can also remove some part of torque from the body by
  333. adding the opposite torque to the body.
  334. >>> t1, t2 = dynamicsymbols('t1 t2')
  335. >>> B.apply_torque(t1*B.x + t2*B.y)
  336. >>> B.loads
  337. [(B_frame, t1(t)*B_frame.x + t2(t)*B_frame.y + t*B_frame.z)]
  338. Let's remove t1 from Body B.
  339. >>> B.apply_torque(-t1*B.x)
  340. >>> B.loads
  341. [(B_frame, t2(t)*B_frame.y + t*B_frame.z)]
  342. To further demonstrate the use, let us consider two bodies such that
  343. a torque `T` is acting on one body, and `-T` on the other.
  344. >>> from sympy.physics.mechanics import Body, dynamicsymbols
  345. >>> with ignore_warnings(DeprecationWarning):
  346. ... N = Body('N') #Newtonion frame
  347. ... B1 = Body('B1')
  348. ... B2 = Body('B2')
  349. >>> v = dynamicsymbols('v')
  350. >>> T = v*N.y #Torque
  351. Now let's apply equal and opposite torque to the bodies.
  352. >>> B1.apply_torque(T, B2)
  353. We can check the loads (torques) applied to bodies now.
  354. >>> B1.loads
  355. [(B1_frame, v(t)*N_frame.y)]
  356. >>> B2.loads
  357. [(B2_frame, - v(t)*N_frame.y)]
  358. Notes
  359. =====
  360. If a new torque is applied on body which already has some torque applied on it,
  361. then the new torque is added to the previous torque about the body's frame.
  362. """
  363. if not isinstance(torque, Vector):
  364. raise TypeError("A Vector must be supplied to add torque.")
  365. if reaction_body is not None:
  366. reaction_body.apply_torque(-torque)
  367. for load in self._loads:
  368. if self.frame in load:
  369. torque += load[1]
  370. self._loads.remove(load)
  371. break
  372. self._loads.append((self.frame, torque))
  373. def clear_loads(self):
  374. """
  375. Clears the Body's loads list.
  376. Example
  377. =======
  378. As Body has been deprecated, the following examples are for illustrative
  379. purposes only. The functionality of Body is fully captured by
  380. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  381. warning we can use the ignore_warnings context manager.
  382. >>> from sympy.utilities.exceptions import ignore_warnings
  383. >>> from sympy.physics.mechanics import Body
  384. >>> with ignore_warnings(DeprecationWarning):
  385. ... B = Body('B')
  386. >>> force = B.x + B.y
  387. >>> B.apply_force(force)
  388. >>> B.loads
  389. [(B_masscenter, B_frame.x + B_frame.y)]
  390. >>> B.clear_loads()
  391. >>> B.loads
  392. []
  393. """
  394. self._loads = []
  395. def remove_load(self, about=None):
  396. """
  397. Remove load about a point or frame.
  398. Parameters
  399. ==========
  400. about : Point or ReferenceFrame, optional
  401. The point about which force is applied,
  402. and is to be removed.
  403. If about is None, then the torque about
  404. self's frame is removed.
  405. Example
  406. =======
  407. As Body has been deprecated, the following examples are for illustrative
  408. purposes only. The functionality of Body is fully captured by
  409. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  410. warning we can use the ignore_warnings context manager.
  411. >>> from sympy.utilities.exceptions import ignore_warnings
  412. >>> from sympy.physics.mechanics import Body, Point
  413. >>> with ignore_warnings(DeprecationWarning):
  414. ... B = Body('B')
  415. >>> P = Point('P')
  416. >>> f1 = B.x
  417. >>> f2 = B.y
  418. >>> B.apply_force(f1)
  419. >>> B.apply_force(f2, P)
  420. >>> B.loads
  421. [(B_masscenter, B_frame.x), (P, B_frame.y)]
  422. >>> B.remove_load(P)
  423. >>> B.loads
  424. [(B_masscenter, B_frame.x)]
  425. """
  426. if about is not None:
  427. if not isinstance(about, Point):
  428. raise TypeError('Load is applied about Point or ReferenceFrame.')
  429. else:
  430. about = self.frame
  431. for load in self._loads:
  432. if about in load:
  433. self._loads.remove(load)
  434. break
  435. def masscenter_vel(self, body):
  436. """
  437. Returns the velocity of the mass center with respect to the provided
  438. rigid body or reference frame.
  439. Parameters
  440. ==========
  441. body: Body or ReferenceFrame
  442. The rigid body or reference frame to calculate the velocity in.
  443. Example
  444. =======
  445. As Body has been deprecated, the following examples are for illustrative
  446. purposes only. The functionality of Body is fully captured by
  447. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  448. warning we can use the ignore_warnings context manager.
  449. >>> from sympy.utilities.exceptions import ignore_warnings
  450. >>> from sympy.physics.mechanics import Body
  451. >>> with ignore_warnings(DeprecationWarning):
  452. ... A = Body('A')
  453. ... B = Body('B')
  454. >>> A.masscenter.set_vel(B.frame, 5*B.frame.x)
  455. >>> A.masscenter_vel(B)
  456. 5*B_frame.x
  457. >>> A.masscenter_vel(B.frame)
  458. 5*B_frame.x
  459. """
  460. if isinstance(body, ReferenceFrame):
  461. frame=body
  462. elif isinstance(body, Body):
  463. frame = body.frame
  464. return self.masscenter.vel(frame)
  465. def ang_vel_in(self, body):
  466. """
  467. Returns this body's angular velocity with respect to the provided
  468. rigid body or reference frame.
  469. Parameters
  470. ==========
  471. body: Body or ReferenceFrame
  472. The rigid body or reference frame to calculate the angular velocity in.
  473. Example
  474. =======
  475. As Body has been deprecated, the following examples are for illustrative
  476. purposes only. The functionality of Body is fully captured by
  477. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  478. warning we can use the ignore_warnings context manager.
  479. >>> from sympy.utilities.exceptions import ignore_warnings
  480. >>> from sympy.physics.mechanics import Body, ReferenceFrame
  481. >>> with ignore_warnings(DeprecationWarning):
  482. ... A = Body('A')
  483. >>> N = ReferenceFrame('N')
  484. >>> with ignore_warnings(DeprecationWarning):
  485. ... B = Body('B', frame=N)
  486. >>> A.frame.set_ang_vel(N, 5*N.x)
  487. >>> A.ang_vel_in(B)
  488. 5*N.x
  489. >>> A.ang_vel_in(N)
  490. 5*N.x
  491. """
  492. if isinstance(body, ReferenceFrame):
  493. frame=body
  494. elif isinstance(body, Body):
  495. frame = body.frame
  496. return self.frame.ang_vel_in(frame)
  497. def dcm(self, body):
  498. """
  499. Returns the direction cosine matrix of this body relative to the
  500. provided rigid body or reference frame.
  501. Parameters
  502. ==========
  503. body: Body or ReferenceFrame
  504. The rigid body or reference frame to calculate the dcm.
  505. Example
  506. =======
  507. As Body has been deprecated, the following examples are for illustrative
  508. purposes only. The functionality of Body is fully captured by
  509. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  510. warning we can use the ignore_warnings context manager.
  511. >>> from sympy.utilities.exceptions import ignore_warnings
  512. >>> from sympy.physics.mechanics import Body
  513. >>> with ignore_warnings(DeprecationWarning):
  514. ... A = Body('A')
  515. ... B = Body('B')
  516. >>> A.frame.orient_axis(B.frame, B.frame.x, 5)
  517. >>> A.dcm(B)
  518. Matrix([
  519. [1, 0, 0],
  520. [0, cos(5), sin(5)],
  521. [0, -sin(5), cos(5)]])
  522. >>> A.dcm(B.frame)
  523. Matrix([
  524. [1, 0, 0],
  525. [0, cos(5), sin(5)],
  526. [0, -sin(5), cos(5)]])
  527. """
  528. if isinstance(body, ReferenceFrame):
  529. frame=body
  530. elif isinstance(body, Body):
  531. frame = body.frame
  532. return self.frame.dcm(frame)
  533. def parallel_axis(self, point, frame=None):
  534. """Returns the inertia dyadic of the body with respect to another
  535. point.
  536. Parameters
  537. ==========
  538. point : sympy.physics.vector.Point
  539. The point to express the inertia dyadic about.
  540. frame : sympy.physics.vector.ReferenceFrame
  541. The reference frame used to construct the dyadic.
  542. Returns
  543. =======
  544. inertia : sympy.physics.vector.Dyadic
  545. The inertia dyadic of the rigid body expressed about the provided
  546. point.
  547. Example
  548. =======
  549. As Body has been deprecated, the following examples are for illustrative
  550. purposes only. The functionality of Body is fully captured by
  551. :class:`~.RigidBody` and :class:`~.Particle`. To ignore the deprecation
  552. warning we can use the ignore_warnings context manager.
  553. >>> from sympy.utilities.exceptions import ignore_warnings
  554. >>> from sympy.physics.mechanics import Body
  555. >>> with ignore_warnings(DeprecationWarning):
  556. ... A = Body('A')
  557. >>> P = A.masscenter.locatenew('point', 3 * A.x + 5 * A.y)
  558. >>> A.parallel_axis(P).to_matrix(A.frame)
  559. Matrix([
  560. [A_ixx + 25*A_mass, A_ixy - 15*A_mass, A_izx],
  561. [A_ixy - 15*A_mass, A_iyy + 9*A_mass, A_iyz],
  562. [ A_izx, A_iyz, A_izz + 34*A_mass]])
  563. """
  564. if self.is_rigidbody:
  565. return RigidBody.parallel_axis(self, point, frame)
  566. return Particle.parallel_axis(self, point, frame)