|
from abc import ABC, abstractmethod |
|
from sympy import Symbol, sympify |
|
from sympy.physics.vector import Point |
|
|
|
__all__ = ['BodyBase'] |
|
|
|
|
|
class BodyBase(ABC): |
|
"""Abstract class for body type objects.""" |
|
def __init__(self, name, masscenter=None, mass=None): |
|
|
|
|
|
if not isinstance(name, str): |
|
raise TypeError('Supply a valid name.') |
|
self._name = name |
|
if mass is None: |
|
mass = Symbol(f'{name}_mass') |
|
if masscenter is None: |
|
masscenter = Point(f'{name}_masscenter') |
|
self.mass = mass |
|
self.masscenter = masscenter |
|
self.potential_energy = 0 |
|
self.points = [] |
|
|
|
def __str__(self): |
|
return self.name |
|
|
|
def __repr__(self): |
|
return (f'{self.__class__.__name__}({repr(self.name)}, masscenter=' |
|
f'{repr(self.masscenter)}, mass={repr(self.mass)})') |
|
|
|
@property |
|
def name(self): |
|
"""The name of the body.""" |
|
return self._name |
|
|
|
@property |
|
def masscenter(self): |
|
"""The body's center of mass.""" |
|
return self._masscenter |
|
|
|
@masscenter.setter |
|
def masscenter(self, point): |
|
if not isinstance(point, Point): |
|
raise TypeError("The body's center of mass must be a Point object.") |
|
self._masscenter = point |
|
|
|
@property |
|
def mass(self): |
|
"""The body's mass.""" |
|
return self._mass |
|
|
|
@mass.setter |
|
def mass(self, mass): |
|
self._mass = sympify(mass) |
|
|
|
@property |
|
def potential_energy(self): |
|
"""The potential energy of the body. |
|
|
|
Examples |
|
======== |
|
|
|
>>> from sympy.physics.mechanics import Particle, Point |
|
>>> from sympy import symbols |
|
>>> m, g, h = symbols('m g h') |
|
>>> O = Point('O') |
|
>>> P = Particle('P', O, m) |
|
>>> P.potential_energy = m * g * h |
|
>>> P.potential_energy |
|
g*h*m |
|
|
|
""" |
|
return self._potential_energy |
|
|
|
@potential_energy.setter |
|
def potential_energy(self, scalar): |
|
self._potential_energy = sympify(scalar) |
|
|
|
@abstractmethod |
|
def kinetic_energy(self, frame): |
|
pass |
|
|
|
@abstractmethod |
|
def linear_momentum(self, frame): |
|
pass |
|
|
|
@abstractmethod |
|
def angular_momentum(self, point, frame): |
|
pass |
|
|
|
@abstractmethod |
|
def parallel_axis(self, point, frame): |
|
pass |
|
|