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

Diagrams.Geom

Geometry utilities used by the rest of the library.

Transforms

type Transform = Translate Float Float | Rotate Float | Scale Float
applyTrans : Transform -> Point -> Point
invertTrans : Transform -> Transform

Points

type alias Point = (Float, Float)
magnitude : Point -> Float
pointAdd : Point -> Point -> Point
pointNegate : Point -> Point
pointSubtract : Point -> Point -> Point

Boxes

type alias BBox = { up : Float , down : Float , left : Float , right : Float }

Bounding box

type alias OffsetDimsBox = { offset : (Float, Float) , dims : Dims }

A box defined by its offset and dimensions

type alias Dims = { width : Float , height : Float }

Dimensions

bbox2offsetDims : BBox -> OffsetDimsBox
pointInside : Point -> OffsetDimsBox -> Bool

Other

lerp : (Float, Float) -> (Float, Float) -> Float -> Float

linear interpolation. To map x from interval (imin, imax) to (omin, omax), use:

lerp (omin, omax) (imin, imax) x
type Direction = Up | Down | Left | Right
directionAngle : Direction -> Float

Given a direction, return an angle in radians.

module Diagrams.Geom where

{-| Geometry utilities used by the rest of the library.

# Transforms
@docs Transform, applyTrans, invertTrans

# Points
@docs Point, magnitude, pointAdd, pointNegate, pointSubtract

# Boxes
@docs BBox, OffsetDimsBox, Dims, bbox2offsetDims, pointInside

# Other
@docs lerp, Direction, directionAngle
-}

{-|-}
type Direction = Up | Down | Left | Right

{-| Given a direction, return an angle in radians. -}
directionAngle : Direction -> Float
directionAngle dir =
  case dir of
    Right -> 0
    Up -> (pi)/2
    Left -> pi
    Down -> (3*pi)/2

-- Transforms

{-|-}
type Transform
  = Translate Float Float
  | Rotate Float
  | Scale Float

{-|-}
applyTrans : Transform -> Point -> Point
applyTrans trans (x, y) = 
  case trans of
    Scale s -> (x*s, y*s)
    Rotate angle -> let c = cos angle
                        s = sin angle
                    in (c*x - s*y, s*x + c*y)
    Translate tx ty -> (x + tx, y + ty)

{-|-}
invertTrans : Transform -> Transform
invertTrans t =
  case t of
    Rotate angle -> Rotate (-angle)
    Scale factor -> Scale (1/factor)
    Translate x y -> Translate (-x) (-y)

-- Points

{-|-}
type alias Point =
  (Float, Float)

{-|-}
magnitude : Point -> Float
magnitude (x, y) = sqrt <| (x^2) + (y^2)

-- TODO: vec vs point (issue #15)
{-|-}
pointAdd : Point -> Point -> Point
pointAdd (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

{-|-}
pointNegate : Point -> Point
pointNegate (x, y) = (-x, -y)

{-|-}
pointSubtract : Point -> Point -> Point
pointSubtract a b = a `pointAdd` (pointNegate b)

-- Boxes

{-| Bounding box -}
type alias BBox =
  { up : Float
  , down : Float
  , left : Float
  , right : Float
  }

-- offset is the middle of the box
{-| A box defined by its offset and dimensions -}
type alias OffsetDimsBox =
  { offset : (Float, Float)
  , dims : Dims
  } -- TODO: translate is a vector (?)

{-| Dimensions -}
type alias Dims =
  { width : Float
  , height : Float
  }

{-|-}
bbox2offsetDims : BBox -> OffsetDimsBox
bbox2offsetDims bbox =
  { offset = ((bbox.right - bbox.left)/2, (bbox.up - bbox.down)/2)
  , dims = { width = bbox.right + bbox.left
           , height = bbox.up + bbox.down
           }
  }

{-|-}
pointInside : Point -> OffsetDimsBox -> Bool
pointInside (x, y) {offset, dims} =
  let (ox, oy) = offset
      halfWidth = dims.width/2
      halfHeight = dims.height/2
  in (x >= ox - halfWidth && x <= ox + halfWidth) &&
       (y >= oy - halfHeight && y <= oy + halfHeight)

-- Other

{-| linear interpolation. To map x from interval (imin, imax) to (omin, omax), use:

    lerp (omin, omax) (imin, imax) x

-}
lerp : (Float, Float) -> (Float, Float) -> Float -> Float
lerp (omin, omax) (imin, imax) input =
  omin + (omax - omin) * (input - imin) / (imax - imin)