Racket Drawing Toolkit – 3

Prima NugrohoContinuo, oggi qui: [doc]/draw/overview.html#(part._.Drawing_.Paths).

Disegnare linee composte (paths)

Drawing functions like draw-line and draw-rectangle are actually convenience functions for the more general draw-path operation. The draw-path operation takes a path, which describes a set of line segments and curves to draw with the pen and—in the case of closed set of lines and curves—fill with the current brush.

An instance of dc-path% holds a path. Conceptually, a path has a current pen position that is manipulated by methods like move-to, line-to, and curve-to. The move-to method starts a sub-path, and line-to and curve-to extend it. The close method moves the pen from its current position in a straight line to its starting position, completing the sub-path and forming a closed path that can be filled with the brush. A dc-path% object can have multiple closed sub-paths and one final open path, where the open path is drawn only with the pen.

For example,

(define zee (new dc-path%))
(send zee move-to 0 0)
(send zee line-to 30 0)
(send zee line-to 0 30)
(send zee line-to 30 30)

creates an open path. Drawing this path with a black pen of width 5 and a transparent brush produces

pict_11

Drawing a single path with three line segments is not the same as drawing three separate lines. When multiple line segments are drawn at once, the corner from one line to the next is shaped according to the pen’s join style. The image above uses the default 'round join style. With 'miter, line lines are joined with sharp corners:

pict_12

If the sub-path in zee is closed with close, then all of the corners are joined, including the corner at the initial point:

(send zee close)

pict_13

Using blue-brush instead of a transparent brush causes the interior of the path to be filled:

pict_14

When a sub-path is not closed, it is implicitly closed for brush filling, but left open for pen drawing. When both a pen and brush are available (i.e., not transparent), then the brush is used first, so that the pen draws on top of the brush.

At this point we can’t resist showing an extended example using dc-path% to draw the Racket logo:

Ho fatto qualche modifica, ho anche usato un paio di immagini fire.png e water.png, queste (yep, piccolissime, per vederle ingrandire il logo):

firewater

#lang racket

(require racket/draw)

(define red-brush (new brush% [stipple (read-bitmap "fire.png")]))
(define blue-brush (new brush% [stipple (read-bitmap "water.png")]))

(define left-lambda-path
  (let ([p (new dc-path%)])
    (send p move-to 153 44)
    (send p line-to 161.5 60)
    (send p curve-to 202.5 49 230 42 245 61)
    (send p curve-to 280.06 105.41 287.5 141 296.5 186)
    (send p curve-to 301.12 209.08 299.11 223.38 293.96 244)
    (send p curve-to 281.34 294.54 259.18 331.61 233.5 375)
    (send p curve-to 198.21 434.63 164.68 505.6 125.5 564)
    (send p line-to 135 572)
    p))
 
(define left-logo-path
  (let ([p (new dc-path%)])
    (send p append left-lambda-path)
    (send p arc 0 0 630 630 (* 47/72 2 pi) (* 121/360 2 pi) #f)
    p))
 
(define bottom-lambda-path
  (let ([p (new dc-path%)])
    (send p move-to 135 572)
    (send p line-to 188.5 564)
    (send p curve-to 208.5 517 230.91 465.21 251 420)
    (send p curve-to 267 384 278.5 348 296.5 312)
    (send p curve-to 301.01 302.98 318 258 329 274)
    (send p curve-to 338.89 288.39 351 314 358 332)
    (send p curve-to 377.28 381.58 395.57 429.61 414 477)
    (send p curve-to 428 513 436.5 540 449.5 573)
    (send p line-to 465 580)
    (send p line-to 529 545)
    p))
 
(define bottom-logo-path
  (let ([p (new dc-path%)])
    (send p append bottom-lambda-path)
    (send p arc 0 0 630 630 (* 157/180 2 pi) (* 47/72 2 pi) #f)
    p))
 
(define right-lambda-path
  (let ([p (new dc-path%)])
    (send p move-to 153 44)
    (send p curve-to 192.21 30.69 233.21 14.23 275 20)
    (send p curve-to 328.6 27.4 350.23 103.08 364 151)
    (send p curve-to 378.75 202.32 400.5 244 418 294)
    (send p curve-to 446.56 375.6 494.5 456 530.5 537)
    (send p line-to 529 545)
    p))
 
(define right-logo-path
  (let ([p (new dc-path%)])
    (send p append right-lambda-path)
    (send p arc 0 0 630 630 (* 157/180 2 pi) (* 121/360 2 pi) #t)
    p))
 
(define lambda-path
  (let ([p (new dc-path%)])
    (send p append left-lambda-path)
    (send p append bottom-lambda-path)
    (let ([t (new dc-path%)])
        (send t append right-lambda-path)
        (send t reverse)
        (send p append t))
    (send p close)
    p))
 
(define (paint-racket dc)
  (send dc set-pen "black" 0 'transparent)
  (send dc set-brush "white" 'solid)
  (send dc draw-path lambda-path)
 
  (send dc set-pen "black" 4 'solid)
 
  (send dc set-brush red-brush)
  (send dc draw-path left-logo-path)
  (send dc draw-path bottom-logo-path)
 
  (send dc set-brush blue-brush)
  (send dc draw-path right-logo-path))
 
(define racket-logo (make-bitmap 170 170))
(define dc (new bitmap-dc% [bitmap racket-logo]))
 
(send dc set-smoothing 'smoothed)
(send dc translate 5 5)
(send dc scale 0.25 0.25)
(paint-racket dc)
     
(send racket-logo save-file "logo.png" 'png)

logo

In addition to the core move-to, line-to, curve-to, and close methods, a dc-path% includes many convenience methods, such as ellipse for adding a closed elliptical sub-path to the path.

Continua, appena mi riprendo 😉
:mrgreen:

Posta un commento o usa questo indirizzo per il trackback.

Trackback

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: