This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
README

Particle

A Particle has mass, position, velocity, and shape.

  • Construct a particle using make mass position velociy shape.

  • Use draw particle to obtain an Svg representation of a particle.

  • Use update t force particle to return an updated version of the particle under the influence of the given force acting for time t.

  • Use orbit n stepper initiaValue to obtain the "orbit" of a particle consisting of n updates using the stepper function.

A stepper function is of type Particle -> Particle. As an example, consider the function

  sf = Particle.update 0.75 force,

where force = Vector 0 -5 is force vector and 0.75 is an interval of time. Then sf, which is a partial application of Particle.update, is a stepper function.

type alias Particle = { position : Vector , velocity : Vector , mass : Float , shape : Shape }

A record type which models a massive particle

type alias Field = Vector -> Vector

A field assigns to each position vector another vector representing the field at that location.

constantField : Vector -> Field

Construct a constant field.

draw : Particle -> Svg.Svg msg

Return an SVG representation of a particle

make : Float -> Vector -> Vector -> Shape -> Particle

Make a particle of given mass, position, velocity and shape.

orbit : Int -> Stepper -> Particle -> List Particle

Compute [a, f a, f^2 a, ..., f^n a]

affineTransform : Affine.Coefficients -> Particle -> Particle

Apply an affine transformation to a particle.

update : Float -> Field -> Particle -> Particle

Given a field and an initial particle, find the particle obtained by evolving the initial particle under the influence of the field for a time t.

module Particle exposing (Particle, Field, constantField, draw, make, orbit, affineTransform, update)

{-| A `Particle` has mass, position, velocity, and shape.

  - Construct a particle using `make mass position velociy shape`.

  - Use `draw particle` to obtain an Svg representation of a particle.

  - Use `update t force particle` to return an updated version of the
    particle under the influence of the given force acting for time t.

  - Use `orbit n stepper initiaValue` to obtain the "orbit" of a particle
    consisting of n updates using the `stepper` function.

A `stepper` function is of type `Particle -> Particle`. As an example,
consider the function

      sf = Particle.update 0.75 force,

where `force = Vector 0 -5` is force vector and 0.75 is an interval of time. Then
`sf`, which is a partial application of `Particle.update`, is a stepper
function.

@docs Particle, Field, constantField, draw, make, orbit, affineTransform, update

-}

import Affine
import Shape exposing (Shape(..), moveTo)
import Svg
import Vector exposing (Vector, add, mul)


{-| A record type which models a massive particle
-}
type alias Particle =
    { position : Vector
    , velocity : Vector
    , mass : Float
    , shape : Shape
    }


{-| A field assigns to each position vector another vector representing the field at
that location.
-}
type alias Field =
    Vector -> Vector


type alias Stepper =
    Particle -> Particle


{-| Construct a constant field.
-}
constantField : Vector -> Field
constantField f =
    \v -> f


{-| Make a particle of given mass, position, velocity and shape.
-}
make : Float -> Vector -> Vector -> Shape -> Particle
make mass position velocity shape =
    let
        shape_ =
            Shape.moveTo position shape
    in
        { position = position, velocity = velocity, mass = mass, shape = shape_ }


{-| Compute [a, f a, f^2 a, ..., f^n a]
-}
orbit : Int -> Stepper -> Particle -> List Particle
orbit n stepper initiaValue =
    orbitAux n stepper [ initiaValue ]


orbitAux : Int -> Stepper -> List Particle -> List Particle
orbitAux n stepper acc =
    if n == 0 then
        acc
    else
        orbitAux (n - 1) stepper (step stepper acc ++ acc)


step : Stepper -> List Particle -> List Particle
step stepper list =
    List.map stepper (List.take 1 list)


{-| Return an SVG representation of a particle
-}
draw : Particle -> Svg.Svg msg
draw particle =
    Shape.draw particle.shape


{-| Given a field and an initial particle, find the particle obtained
by evolving the initial particle under the influence of the field for
a time `t`.
-}
update : Float -> Field -> Particle -> Particle
update t field particle =
    let
        displacement =
            mul t particle.velocity

        newPosition =
            add particle.position displacement

        acceleration =
            mul (1 / particle.mass) (field newPosition)

        newVelocity =
            add (mul t acceleration) particle.velocity

        newShape =
            Shape.moveTo newPosition particle.shape
    in
        { particle | position = newPosition, velocity = newVelocity, shape = newShape }


{-| Apply an affine transformation to a particle.
-}
affineTransform : Affine.Coefficients -> Particle -> Particle
affineTransform coefficients particle =
    let
        newShape =
            Shape.affineTransform coefficients particle.shape
    in
        { particle | shape = newShape }