w0rm/elm-physics/5.0.0

NOTE: the latest version is 6.2.0

Physics.Body

type alias Body data =
Protected data

Represents a physical body containing user defined data, like a WebGL mesh.

By default bodies don’t move. To change this, use withBehavior.

All bodies start out centered on the origin, use moveTo to set the position.

The supported bodies are:

For complex bodies check compound.

block : Block3d Meters BodyCoordinates -> data -> Body data

A block is created from elm-geometry Block3d. To create a 1x1x1 cube, centered at the origin of the body, call this:

cubeBody =
    block
        (Block3d.centeredOn
            Frame3d.origin
            ( meters 1, meters 1, meters 1 )
        )
        data
plane : data -> Body data

A plane with the normal that points in the direction of the z axis.

A plane is collidable in the direction of the normal. Planes don’t collide with other planes and are always static.

sphere : Sphere3d Meters BodyCoordinates -> data -> Body data

A sphere is created from elm-geometry Sphere3d.

To create a 1 meter radius sphere, that is centered at the origin of the body, call this:

sphereBody =
    sphere
        (Sphere3d.atOrigin (meters 1))
        data
particle : data -> Body data

A particle is an abstract point that doesn’t have dimensions. Particles don’t collide with each other.

Behavior

Bodies may have static or dynamic behavior.

dynamic : Mass -> Behavior

Dynamic bodies move and react to forces and collide with other dynamic and static bodies.

Static bodies don’t move and only collide with dynamic bodies.

withBehavior : Behavior -> Body data -> Body data

Change the behavior, e.g. to make a body dynamic:

dynamicBody =
    staticBody
        |> withBehavior (dynamic (Mass.kilograms 5))

Properties

Body data
-> Frame3d Meters WorldCoordinates { defines : BodyCoordinates }

Get the position and orientation of the body in the world as Frame3d.

This is useful to transform points and directions between world and body coordinates.

originPoint : Body data -> Point3d Meters WorldCoordinates

Get the origin point of a body in the world

velocity : Body data -> Vector3d MetersPerSecond WorldCoordinates

Get the linear velocity of a body

angularVelocity : Body data -> Vector3d RadiansPerSecond WorldCoordinates

Get the angular velocity of a body

centerOfMass : Body data -> Point3d Meters BodyCoordinates

Get the center of mass of a body in the body coordinate system.

Position and orientation

moveTo : Point3d Meters WorldCoordinates -> Body data -> Body data

Set the position of the body in the world, e.g. to raise a body 5 meters above the origin:

movedBody =
    body
        |> moveTo (Point3d.meters 0 0 5)
translateBy : Vector3d Meters WorldCoordinates -> Body data -> Body data

Move the body in the world relative to its current position, e.g. to translate a body down by 5 meters:

translatedBody =
    body
        |> translateBy (Vector3d.meters 0 0 -5)
rotateAround : Axis3d Meters WorldCoordinates -> Angle -> Body data -> Body data

Rotate the body in the world around axis, e.g. to rotate a body 45 degrees around Z axis:

movedBody =
    body
        |> rotateAround Axis3d.z (Angle.degrees 45)

User-Defined Data

data : Body data -> data

Get user-defined data.

withData : data -> Body data -> Body data

Update user-defined data.

Interaction

Quantity Float Newtons
-> Direction3d WorldCoordinates
-> Point3d Meters WorldCoordinates
-> Body data
-> Body data

Apply a force in a direction at a point on a body. The force will be applied during one simulation step.

Keep applying the force every simulation step to accelerate.

pushedBox =
    box
        |> applyForce
            (Force.newtons 50)
            Direction3d.positiveY
            pointOnBox
Quantity Float (Product Newtons Seconds)
-> Direction3d WorldCoordinates
-> Point3d Meters WorldCoordinates
-> Body data
-> Body data

Apply an impulse in a direction at a point on a body. Applying an impulse is the same as applying a force during the interval of time. The changes are applied to velocity and angular velocity of the body.

For example, to hit a billiard ball with a force of 50 newtons, with the duration of the hit 0.005 seconds:

impulse =
    Force.newtons 50
        |> Quantity.times (Duration.seconds 0.005)


hitCueBall =
    cueBall
        |> applyImpulse
            impulse
            Direction3d.positiveY
            hitPoint

Advanced

withMaterial : Material -> Body data -> Body data

Set the material to controll friction and bounciness.

compound : List Shape -> data -> Body data

Make a compound body from a list of shapes.

For example, the sphere from above can be defined like this:

sphere radius data =
    compound
        [ Shape.sphere
            (Sphere3d.atOrigin (meters 1))
        ]
        data

We only support rigid bodies.

{ linear : Float
, angular : Float
}
-> Body data
-> Body data

Set linear and angular damping, in order to decrease velocity over time.

This may be useful to e.g. simulate the friction of a sphere rolling on the flat surface. The normal friction between these surfaces doesn’t work, because there is just 1 contact point.

Inputs are clamped between 0 and 1, the defaults are 0.01.