Coordinates
1 Curves
5.90.0.9

Coordinates

1 Curves

All shapes in MetaPicts are built of curves. There are several ways of describing curves, but the simplest and most common is to describe some points on the curves and how to connect them.

In the chapter on points, we used (draw (curve p1 .. p6)) to connect the points p1 and p6 with a straight line. If more than two points are connected with the connector .., then MetaPict will connect the points with a "pretty", smooth curve.

> (draw (curve p4 .. p1 .. p2 .. p6))

> (draw (curve p5 .. p4 .. p1 .. p3 .. p6 .. p5))

The last curve is not smooth at p5 which is the start and ending point. To modify the expression to get a smooth, closed curve, use cycle as the "end point" rather than repeat the start point.
> (draw (curve p5 .. p4 .. p1 .. p3 .. p6 .. cycle))

There are various ways of controlling the curve. Adding a direction after a point will make the curve leave the point in that direction.

> "TODO - fix me"

"TODO - fix me"

> (draw
   red-todo-fix
   (curve p5 .. p4 left .. p1 .. p3 .. p6 left .. cycle))

> (draw (curve p5 .. p4 left .. p1 .. p3 .. p6 left .. p5))

Here left stands for the direction (vec -1 0). You can use any vector you like. The expression (draw (curve p1 .. p2 (pt- p3 p1) .. p3)) will draw a curve from p1 through p2 to p3 and the tangent in p2 will be parallel with the vector from p1 to p3.

> (draw (curve p4 .. p2 (pt- p3 p4) .. p3))

Let us connect two points and see what happens when we vary the direction from which the curve leaves the first point. We use (dir d) to specify a unit vector whose angle with the x-axis are d degrees.

> (draw* (for/list ([d (in-range 0 100 10)])
           (curve (pt 0 0) (dir d) .. (pt 300 0))))

Here the function draw* draws all curves in a list on the same pict. We notice that MetaPict thinks "circle arcs" are the pretties way of joining two point, when only one direction is specified.

Let us see what happens when we fix the direction in which the curve enters the end point.
> (draw* (for/list ([d (in-range 0 100 15)])
           (curve (pt 0 0) (dir d) .. right (pt 300 0))))

You can use curl to change the how much the curve "curls" at the start and end point.

> "TODO - fix this"

"TODO - fix this"

> (draw red-todo-fix
        (curve (curl 0) p4 .. p2 (pt- p3 p4) .. p3 (curl 3)))

path:: First element of a path must be a point (i.e. a pt

structure). Got #(struct:curl 0)

> (list (draw (curve  p4 (curl 0) .. p6))
        (draw (curve  p4 (curl 1) .. p6))
        (draw (curve  p4 (curl 2) .. p6))
        (draw (curve  p4 (curl 3) .. p6)))

'(   )

> "TODO - fix this"

"TODO - fix this"

> (draw red-todo-fix
        (curve p4 (controls p1 p2) p6))

match: no matching clause for (list (pt 0 0) (full-join

(curl 1) (controls-and (pt 0 100) (pt 100 100)) (curl 1))

(pt 200 0))