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

# 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 =

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

newVelocity =

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 }
```
```