diff --git a/src/Physics/Classes/Mass.hs b/src/Physics/Classes/Mass.hs index 3064cb2..67b8133 100644 --- a/src/Physics/Classes/Mass.hs +++ b/src/Physics/Classes/Mass.hs @@ -9,11 +9,11 @@ class Mass m where -- | The mass of the mass object. mass :: m -> Double - -- | Retrieve the acceleration of the mass object. - acceleration :: m -> V2 Double + -- | Retrieve the position of the mass object. + position :: m -> V2 Double - -- | Overwrite the acceleration of the mass object. - accelerationUpdater :: m -> (V2 Double -> m) + -- | Overwrite the position of the mass object. + positionUpdater :: m -> (V2 Double -> m) -- | retrieve the velocity of the mass object. velocity :: m -> V2 Double @@ -21,42 +21,35 @@ class Mass m where -- | Overwrite the velocity of the mass object. velocityUpdater :: m -> (V2 Double -> m) - -- | Retrieve the position of the mass object. - position :: m -> V2 Double + -- | Total force acting on a particle in one simulation step + forces :: m -> V2 Double - -- | Overwrite the position of the mass object. - positionUpdater :: m -> (V2 Double -> m) + -- | Overwrite the forces acting on a particle + forcesUpdater :: m -> (V2 Double -> m) - -- | The update function to let a mass react to gravitational pull. - -- Apply all accelerations before calling the default implementation of - -- this function, since it will add the gravitational pull to already - -- existing accelerations. - gravitate - :: V2 Double -- ^ Vector of gravitational acceleration - -> m -- ^ Original mass object - -> m -- ^ Updated mass object - gravitate g m = - let acc = acceleration m + g + -- | Reset forces vector for the begining of a new simulation step + resetForces :: m -> m + resetForces m = forcesUpdater m (V2 0 0) + + -- | Calculate the loads or forces acting on the mass object except for + -- collision forces. + addLoads + :: m -- ^ The mass object + -> V2 Double -- ^ force to be aggregated acting on the particle (e.g.: gravity) + -> m -- ^ Resulting mass object + addLoads m vec = + forcesUpdater m (forces m + vec) + + -- | Euler integration updates + updateByEuler + :: m -- ^ The mass object + -> Double -- ^ Time step in fraction of a second + -> m -- ^ Resulting mass object + updateByEuler m dt = + let acc = (/ mass m) <$> forces m + dvel = (* dt) <$> acc + nvel = velocity m + dvel + dpos = (* dt) <$> nvel + npos = position m + dpos in - accelerationUpdater m acc - - -- | Apply acceleration to mass object und thus change its velocity - accelerate - :: Double -- ^ Time step duration - -> m -- ^ Original mass object - -> m -- ^ Updated mass object - accelerate dt m = - let vel = velocity m + ((dt *) <$> acceleration m) - in - velocityUpdater m vel - - -- | Apply velocity to mass object and thus change its position - -- Changes in position smaller than around half a pixel per second are ignored. - move - :: Double -- ^ Time step duration - -> m -- ^ Original mass object - -> m -- ^ Updated mass object - move dt m = - let dpos = (dt *) <$> velocity m - in - positionUpdater m (position m + dpos) + positionUpdater (velocityUpdater m nvel) npos