Patch title: Release 85 bulk changes
Abstract:
File: /pliant/math/transform.pli
Key:
    Removed line
    Added line
submodule "point.pli"
submodule "vector.pli"
submodule "functions.pli"
module "matrix.pli"

doc
  [If zero is a bottom left, then rotate is counterclockwise, just as in PostScript coordinate system.] ; eol
  [If zero is a top left, than rotate is clockwise]

public
  constant transform_identity 0
  constant transform_translate 1
  constant transform_scale 2
  constant transform_rotate 3

  type Transform2
    field Float xx xy xt
    field Float yx yy yt
    field Int level


method t compute
  arg_rw Transform2 t
  if t:xy<>0 or t:yx<>0
    t level := transform_rotate
  eif t:xx<>1 or t:yy<>1
    t level := transform_scale
  eif t:xt<>0 or t:yt<>0
    t level := transform_translate
  else
    t level := transform_identity


function transform -> t
  arg Transform2 t
  t xx := 1
  t xy := 0
  t xt := 0
  t yx := 0
  t yy := 1
  t yt := 0
  t level := transform_identity

function transform tx ty sx sy rx ry -> t
  arg Float tx ty sx sy rx ry ; arg Transform2 t
  if (rx<>0 or ry<>0)
    t xx := sx*cos:rx
    t xy := -sy*sin:ry
    t xt := tx
    t yx := sx*sin:rx
    t yy := sy*cos:ry
    t yt := ty
  else
    t xx := sx
    t xy := 0
    t xt := tx
    t yx := 0
    t yy := sy
    t yt := ty
  t compute


method t matrix -> m
  arg Transform2 t ; arg Matrix m
  m resize 3 3
  m 0 0 := t xx
  m 0 1 := t xy
  m 0 2 := t xt
  m 1 0 := t yx
  m 1 1 := t yy
  m 1 2 := t yt
  m 2 0 := 0
  m 2 1 := 0
  m 2 2 := 1

function transform m -> t
  arg Matrix m ; arg Transform2 t
  check m:nb_lines=3 and m:nb_columns=3
  t xx := m 0 0
  t xy := m 0 1
  t xt := m 0 2
  t yx := m 1 0
  t yy := m 1 1
  t yt := m 1 2
  t compute

function compose t1 t2 -> t
  arg Transform2 t1 t2 t
  t := transform t2:matrix*t1:matrix

function compose t1 t2 t3 -> t
  arg Transform2 t1 t2 t3 t
  t := transform t3:matrix*t2:matrix*t1:matrix

function reverse t -> inv
  arg Transform2 t inv
  inv := transform t:matrix^(-1)


method t '' p -> q
  arg Transform2 t ; arg Point2 p q
  if t:level=transform_identity
    q := p
  eif t:level=transform_translate
    q := point p:x+t:xt p:y+t:yt
  eif t:level=transform_scale
    q := point p:x*t:xx+t:xt p:y*t:yy+t:yt
  else
    q := point p:x*t:xx+p:y*t:xy+t:xt p:x*t:yx+p:y*t:yy+t:yt

method t '' v -> w
  arg Transform2 t ; arg Vector2 v w
  if t:level<=transform_translate
    w := v
  eif t:level=transform_scale
    w := vector v:x*t:xx v:y*t:yy
  else
    w := vector v:x*t:xx+v:y*t:xy v:x*t:yx+v:y*t:yy


export Transform2 '. compute' transform '' '. matrix' compose reverse