Ipelib
Lua bindings for geometric objects

All Ipelib objects have constructors of the form:

``` v = ipe.Vector()
m = ipe.Matrix()
m = ipe.Translation()  -- another Matrix constructor
m = ipe.Rotation()     -- yet another Matrix constructor
r = ipe.Rect()
l = ipe.Line()
l = ipe.LineThrough()  -- another Line constructor
l = ipe.Bisector()     -- yet another Line constructor
s = ipe.Segment()
b = ipe.Bezier()
a = ipe.Arc()
```

Note that ipe::Angle and ipe::Linear are not bound in Lua. Use numbers and ipe.Matrix instead. A useful method for angles is:

```beta = ipe.normalizeAngle(alpha, lowLimit)
```

# Vector

ipe.Vector binds ipe::Vector. There are the following methods:

```v = ipe.Vector()         -- zero vector
v = ipe.Vector(x, y)
v = ipe.Direction(alpha) -- unit vector in this direction
b = v.y

v:len() -- returns norm of vector
v:sqLen() -- returns square of norm
v:normalized() -- returns this vector normalized
v:orthogonal() -- returns this vector rotated left by 90 degrees
v:factorize(u) -- factors v = lambda u + x, where x orth. to u, u is unit
v:angle()     -- return direction
v == w        -- vector equality
v ~= w
-v            -- unary minus
v + w         -- vector addition
v - w         -- vector difference
5 * v         -- multiplication with a scalar
v * 5         -- multiplication with a scalar
v .. w        -- dot product
```

# Matrix

ipe.Matrix binds ipe::Matrix. It has the following methods:

```m = ipe.Matrix()                        -- identity matrix
m = ipe.Matrix(a1, a2, a3, a4)          -- linear transformation
m = ipe.Matrix(a1, a2, a3, a4, a5, a6)  -- affine transformation
m = ipe.Matrix( { a1, a2, a3, a4, a5, a6 } ) -- same from table
m = ipe.Rotation(alpha)                 -- rotation matrix
m = ipe.Translation(v)                  -- v is a vector
m = ipe.Translation(x, y)

m1 == m2          -- matrix equality
m1 * m2           -- matrix multiplication
m * v             -- matrix * vector
m * arc           -- matrix * arc

m:elements()      -- returns six-element array with elements

m:isIdentity()
m:isSingular()
m:inverse()
m:translation()   -- return translation component
m:linear()        -- returns matrix without the translation component
```

# Rect

ipe.Rect binds ipe::Rect. This is the only mutable geometric object - take care not to be surprised when ipe.Rect objects are shared.

It has the following methods:

```r = ipe.Rect()    -- empty
r:isEmpty()
r:topRight()
r:bottomLeft()
r:topLeft()
r:bottomRight()
r:left()
r:right()
r:bottom()
r:top()
r:width()
r:height()
r:add(v)          -- extend to cover vector v
r1:add(r2)        -- extend to cover rectangle r2
r1:clipTo(r2)     -- clip r1 to lie inside r2
r:contains(v)
r1:contains(r2)
r1:intersects(r2)
```

# Line

ipe.Line binds ipe::Line. It has the following methods:

```l = ipe.Line(p, dir)      -- dir must be unit vector
l = ipe.LineThrough(p, q)
l = ipe.Bisector(p, q)

-- l:side() returns +1 if v lies to the left side of the line,
-- 0 if on line, -1 if on the right side
l:side(v)
l:point()                 -- starting point of line
l:dir()                   -- unit direction vector
l:normal()                -- unit normal vector pointing to the left side
l:distance(v)             -- returns distance from point to line
l1:intersects(l2)         -- returns intersection point or nil
l:project(p)              -- projection of point on line
```

# Segment

ipe.Segment binds ipe::Segment. It has the following methods:

```s = ipe.Segment(p, q)
p, q = s:endpoints()      -- returns both endpoints
s:line()                  -- returns an ipe.Line
s:project(p)              -- returns projection or nil
s:distance(p)
s:intersects(l)           -- return intersection point or nil
s1:intersects(s2)
```

# Bezier

ipe.Bezier binds ipe::Bezier. It has the following methods:

```b = ipe.Bezier(v1, v2, v3, v4)
b:point(t)                -- point at value t
v1, v2, v3, v4 = b:controlpoints()  -- returns all four control points
b:bbox()
t, p = b:snap(pos)

-- intersections:
-- x is line, segment, or bezier
-- returns table of intersection points
b:intersect(x)
```

# Arc

ipe.Arc binds ipe::Arc. It has the following methods:

```a = ipe.Arc(m)            -- ellipse defined by ipe.Matrix m
a = ipe.Arc(m, p, q)      -- arc from p to q
a = ipe.Arc(m, alpha, beta)

a:endpoints()             -- returns two endpoints
a:angles()                -- returns two angles
a:bbox()
a:matrix()
a:isEllipse()
alpha, p = a:snap(pos)

-- intersections:
-- x is line, segment, arc, or bezier
-- returns table of intersection points
a:intersect(x)
```