This blog post shows to use the racket/draw library to draw Bezier curves.
A Bezier curve connects two points, so we need a way to represent points.
(struct pt (x y))
A Bezier curve from p0 to p3 with control points p1 and p2 is represented by a bez structure:
(struct bez (p0 p1 p2 p3))
Given these structure definitions we can now represent Picasso’s Dachshund (see Jeremy Kun’s Blog).
(define dachshund |
(list |
(bez (pt 180 280) (pt 183 263) (pt 186 256) (pt 189 244)) |
(bez (pt 191 244) (pt 290 244) (pt 300 230) (pt 339 245)) |
(bez (pt 340 246) (pt 350 290) (pt 360 300) (pt 355 210)) |
(bez (pt 353 210) (pt 370 207) (pt 380 196) (pt 375 193)) |
(bez (pt 375 193) (pt 310 220) (pt 190 220) (pt 164 205)) |
(bez (pt 164 205) (pt 135 194) (pt 135 265) (pt 153 275)) |
(bez (pt 153 275) (pt 168 275) (pt 170 180) (pt 150 190)) |
(bez (pt 149 190) (pt 122 214) (pt 142 204) (pt 85 240)) |
(bez (pt 86 240) (pt 100 247) (pt 125 233) (pt 140 238)))) |
The racket/draw library represents Bezier curves (or rather zero or more closed subpaths and one open subpath) as dc-path% objects. The function bez->dc-path converts the representation of a Bezier curve from a bez structure into dc-path%.
It is now trivial to define a function, that draws a Bezier curve using a given drawing context, dc:
The dachshund is drawn piece by piece:
Using drawing contexts allow to use the same draw-dachshund function to draw the dachshund on pdfs, bitmaps, and, more. Let’s draw the dachshund on a bitmap.
(define bm (make-object bitmap% 400 100)) |
(define dc (new bitmap-dc% [bitmap bm])) |
(send dc set-smoothing 'smoothed) |
(send dc set-pen "red" 1 'solid) |
(send dc translate 0 -185) |
(draw-dachshund dc) |
bm |
To run the code in this blog post, the pieces must be assembled in this order.
(require racket racket/draw) |
(provide bm) |
<pt-definition> |
<bez-definition> |
<dachshund> |
<conversion> |
<draw-bez> |
<draw-dachshund> |
<example> |