Grafica con newLISP – 3


Dov’ero rimasto? Ah sì, c’è in sospeso la promessa a Giulia R. (non la maghetta: 2011 -> tante giulie, tutte super-über-geek) di un ghirigoro come quelli fattibili con lo spirograph.
Beh, facile, ormai ci abbiamo preso la mano nei due post dedicati all’argomento, qui e qui.

Allora, anche se lo so che non sono tanto bravo a disegnare ecco lo schema che verrà implementato

Abbiamo la biella viola di lunghezza Lp incernierata nel punto C che ruota con velocità angolare ωp. All’estremità P della biella è incernierata la biella verde di lunghezza Ls ruotante con velocità ωs.
Lo script visualizzerà il percorso compiuto dai punti P e S. Inoltre le tracce dei due punti cambiano di colore a ogni passo e le aste variano di lunghezza da un minimo a un massimo.

OK, proporrei di fare le cose un passo per volta. Sì?

La prima versione è davvero semplice: solo l’asta principale e la traccia tutta nera; per vedere se è tutto a posto disegno poi un cerchio rosso: se le due curve coincidono il disegno è perfetto.

#!/usr/bin/newlisp
;;
;; calypso
(set-locale "C" ".") ;; impo - non dimenticare mai!

(load (append (env "NEWLISPDIR") "/guiserver.lsp"))
(gs:init)
(gs:frame 'Calypso 0 0 400 300 "Calypso")
(gs:set-border-layout 'Calypso)
(gs:canvas 'MyCanvas 'Calypso)
(gs:add-to 'Calypso 'MyCanvas "center")
(gs:set-background 'MyCanvas gs:white)
(gs:set-paint gs:black)

(set 'PI (mul 4 (atan 1))) ; pi
(set 'rd (div PI 180)) ; rapporto rad/gradi
(set 'R 100) ; raggio
(set 'deltaA 3) ; incremento angolo
(set 'xc 200 'yc 150) ; coordinate del centro perno della biella
(set 'xp (+ xc R) 'yp yc) ; coordinate punto precedente

(dotimes (N (/ 360 deltaA))
	(set 'ang (mul rd (+ 1 N) deltaA)
		 'x (+ xc (round (mul R (cos ang))))
		 'y (- yc (round (mul R (sin ang)))))
	(gs:draw-line 'L xp yp x y gs:black)
	(set 'xp x 'yp y)
)
; per confronto un cerchio con lo stesso raggio
(gs:draw-circle 'C xc yc R gs:red)

(gs:set-visible 'Calypso true)
(gs:export "c1.png")

(gs:listen)

OK, può andare, quasi perfettamente perfetto ;-)

È il momento di attivare la variazione della lunghezza dell’asta. Questa parte dal valore medio e varia in funzione di deltaR e del segno di sgnR tra in valori Rmax e Rmin, ecco

#!/usr/bin/newlisp
;;
;; calypso
(set-locale "C" ".") ;; impo - non dimenticare mai!

(load (append (env "NEWLISPDIR") "/guiserver.lsp"))
(gs:init)
(gs:frame 'Calypso 0 0 800 600 "Calypso")
(gs:set-border-layout 'Calypso)
(gs:canvas 'MyCanvas 'Calypso)
(gs:add-to 'Calypso 'MyCanvas "center")
(gs:set-background 'MyCanvas gs:white)
(gs:set-paint gs:black)

(set 'PI (mul 4 (atan 1))) ; pi
(set 'rd (div PI 180)) ; rapporto rad/gradi
(set 'R 100 ; raggio iniziale
	 'Rmin 30 ; raggio minmimo
	 'Rmax 170 ; raggio massimo
	 'deltaR 3 ; passo variazione
	 'sgnR 1) ; inc/dec R
(set 'deltaA 3) ; incremento angolo
(set 'xc 400 'yc 300) ; coordinate del centro perno della biella
(set 'xPp (+ xc R) 'yPp yc) ; coordinate punto precedente
(set 'n (/ 360 deltaA)
	  ' giri 10)

(dotimes (N (* giri n))
	(set 'ang (mul rd (add (mod N n) 1) deltaA)
	     'R (+ R (* sgnR deltaR))
		 'xP (+ xc (round (mul R (cos ang))))
		 'yP (- yc (round (mul R (sin ang)))))
	(gs:draw-line 'L xPp yPp xP yP gs:black)
	(if (or (> R Rmax) (< R Rmin)) (set 'sgnR (* sgnR -1)))
	(set 'xPp xP 'yPp yP)
)

(gs:set-visible 'Calypso true)
(gs:export "c2.png")

(gs:listen)

Il passo successivo è l’introduzione della variazione del colore, usando la funzione c-new-color costruita nella puntata precedente, così

#!/usr/bin/newlisp
;;
;; calypso
(set-locale "C" ".") ;; impo - non dimenticare mai!

(define (c-new-color n , r g b)
	(set 'r (round (div (/ n 100) 9) -1)
	 	 'n (% n 100)
		 'g (round (div (/ n 10) 9) -1)
		 'b (round (div (% n 10) 9) -1))
	(list r g b)
)

(load (append (env "NEWLISPDIR") "/guiserver.lsp"))
(gs:init)
(gs:frame 'Calypso 0 0 800 600 "Calypso")
(gs:set-border-layout 'Calypso)
(gs:canvas 'MyCanvas 'Calypso)
(gs:add-to 'Calypso 'MyCanvas "center")
(gs:set-background 'MyCanvas gs:white)
(gs:set-paint gs:black)

(set 'PI (mul 4 (atan 1))) ; pi
(set 'rd (div PI 180)) ; rapporto rad/gradi
(set 'R 100 ; raggio iniziale
	 'Rmin 30 ; raggio minmimo
	 'Rmax 170 ; raggio massimo
	 'deltaR 3 ; passo variazione
	 'sgnR 1 ; inc/dec R
	 'ncP 0) ; indice colore P
(set 'deltaA 3) ; incremento angolo
(set 'xc 400 'yc 300) ; coordinate del centro perno della biella
(set 'xPp (+ xc R) 'yPp yc) ; coordinate punto precedente
(set 'n (/ 360 deltaA)
	  ' giri 10)

(dotimes (N (* giri n))
	(set 'ang (mul rd (add (mod N n) 1) deltaA)
	     'R (+ R (* sgnR deltaR))
		 'xP (+ xc (round (mul R (cos ang))))
		 'yP (- yc (round (mul R (sin ang)))))
	(gs:draw-line 'L xPp yPp xP yP (c-new-color ncP))
	(if (or (> R Rmax) (< R Rmin)) (set 'sgnR (* sgnR -1)))
	(set 'xPp xP 'yPp yP)
	(set 'ncP (% (inc ncP) 1000))
)

(gs:set-visible 'Calypso true)
(gs:export "c3.png")

(gs:listen)

OK, adesso mettiamo in gioco l’asta secondaria, la cosa diventa interessante. Intanto l’asta secondaria si attiva e fa un giro completo solo ogni 10 passi. La variazione dei colori è indipendente per i due punti P e S. Ecco cosa si ottiente

#!/usr/bin/newlisp
;;
;; calypso
(set-locale "C" ".") ;; impo - non dimenticare mai!

(define (c-new-color n , r g b)
	(set 'r (round (div (/ n 100) 9) -1)
	 	 'n (% n 100)
		 'g (round (div (/ n 10) 9) -1)
		 'b (round (div (% n 10) 9) -1))
	(list r g b)
)

(load (append (env "NEWLISPDIR") "/guiserver.lsp"))
(gs:init)
(gs:frame 'Calypso 0 0 800 600 "Calypso")
(gs:set-border-layout 'Calypso)
(gs:canvas 'MyCanvas 'Calypso)
(gs:add-to 'Calypso 'MyCanvas "center")
(gs:set-background 'MyCanvas gs:white)
(gs:set-paint gs:black)

(set 'PI (mul 4 (atan 1))) ; pi
(set 'rd (div PI 180)) ; rapporto rad/gradi
(set 'R 100 ; raggio iniziale
	 'Rmin 30 ; raggio minmimo
	 'Rmax 170 ; raggio massimo
	 'deltaR 3 ; passo variazione
	 'sgnR 1 ; inc/dec R
	 'ncP 0) ; indice colore P
(set 'deltaA 3) ; incremento angolo
(set 'xc 400 'yc 300) ; coordinate del centro perno della biella
(set 'xPp (+ xc R) 'yPp yc) ; coordinate punto precedente
(set 'n (/ 360 deltaA)
	  ' giri 10)
(set 'Rs0 20 ; dati punto S
     'Rsmin 10
     'Rsmax 40
     'deltaRs 2
     'ncS 500
     'ns 36
	 'conts 0)
(dotimes (N (* giri n))
	(set 'ang (mul rd (add (mod N n) 1) deltaA)
	     'R (+ R (* sgnR deltaR))
		 'xP (+ xc (round (mul R (cos ang))))
		 'yP (- yc (round (mul R (sin ang)))))
	(gs:draw-line 'L xPp yPp xP yP (c-new-color ncP))
	(if (or (> R Rmax) (< R Rmin)) (set 'sgnR (* sgnR -1)))
	(set 'xPp xP 'yPp yP)
	(set 'ncP (% (inc ncP) 1000))

	; punto S
	(inc conts)
	(if (= (% conts 10) 0)
		(set 'angs -10
			 'sgnRs 1
			 'Rs Rs0
			 'xSp (+ xP Rs)
			 'ySp yP)
		(print angs) ; bug?
		(dotimes (ns 36)
			(set 'angs (+ angs 10)
				'Rs (+ Rs (* sgnRs deltaRs))
				'xS (+ xP (round (mul Rs (cos angs))))
				'yS (- yP (round (mul Rs (sin angs)))))
			(gs:draw-line 'L xSp ySp xS yS (c-new-color ncS))
			(if (or (> Rs Rsmax) (< Rs Rsmin))
				(set 'sgnRs (* sgnRs -1)))
			(set 'xSp xS 'ySp yS)
			(set 'ncS (% (inc ncS) 1000))
		)
	)
)
(println)
(gs:set-visible 'Calypso true)
(gs:export "c4.png")

(gs:listen)

C’è presumibilmente un bug in newLISP –non ho capito bene cosa– sta di fatto che inserendo un (print angs) –riga 61– tutto funziona.

Se si cambia il numero di passi per l’attivazione dell’asta secondaria si ottengono, ovviamente, grafici diversi, ecco quello per 20

Doh! (cit.) Credo di aver mantenuto la promessa, vero Giulia? :-D

Poi volendo si potrebbero cambiare tante cose: che ne dite di variare la lunghezza delle aste secondo una funzione sinusoidale?

Sembra un’idea, lasciata come esercizio, quanto sono buono ;-)
E se invece dei cerchi si disegnassero spirali? E temporizzare le tracce, dopo un tot la parte vecchia man mano viene cancellata?

E conoscete Tony, quello che compare nella immagine sopra? Lui sì che è bravo, lo trovate qui

Nelle prossime puntate si cambia: caratteristiche della finestra, pulsanti di vario tipo e quant’altro — forse ;-)

About these ads
Post a comment or leave a trackback: Trackback URL.

Commenti

  • giulia68  On 31 dicembre 2011 at 08:49

    Wow!! Adesso sì che è perfetto!! Hai proprio fatto un lavorone per me, grazie infinite, Juhan, sei davvero uno splendido mago! :)
    Miaooo!

Rispondi

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

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. 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 )

Google+ photo

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

Connessione a %s...

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 71 follower

%d blogger cliccano Mi Piace per questo: