cg-Cad

Lisp »Tips 'n Tricks »Tempi di cottura

Erbe aromatiche, coniglio al ragù e frittelle di riso

FRTR modella in 3d una frittella di riso cosparsa di zucchero.
Per questo lisp ho preso il sorgente per generare un nuvolo temporalesco modificandolo in più punti; per prima cosa ho cambiato la funzione (rn) per generare numeri casuali e le dimensioni delle sfere per simulare il riso (raggio=1) e lo zucchero (raggio=0.1) e ovviamente ho cambiato il colore (anzi i colori)...

;;;
;;;    frtr.lsp Versione 1.0 - 21 Febbraio 2004
;;;    (C) 2004 by Claudio Piccini.
;;;    www.cg-cad.com
;;;    
;;;    Disegna una frittella di riso con
;;;    zucchero 3D.
;;;

(defun myerror (s)                  
  (if (/= s "Function cancelled")
    (princ (strcat "\nError: " s))
  )
 (ripVar)
 (princ)
)

(defun salVar ()
 (setq orto (getvar "orthomode"))
 (setq snapp (getvar "osmode"))
 (setq snm (getvar "snapmode"))
 (setq piano (getvar "clayer"))
)

(defun ripVar ()
 (setvar "cmdecho" 1)
 (setvar "osmode" snapp)
 (setvar "snapmode" snm)
 (setvar "orthomode" orto)
 (setvar "clayer" piano)
 (setvar "cecolor" "BYLAYER")
 (setq *error* olderr)
 (princ)
)

; numeri casuali
(defun rn (sd)
 (setq m 65521 b 15937 c 33503 sd 
  (rem (+ (* b sd) c) m)
 )
 (* (/ sd m) 14)
)

 ;|
     D-----P-----C
     |           |
     |           |
     Q     O     N
     |           |
     |           |
     A-----M-----B
 |;

(defun frittella (conta xA yA xB yB xC yC xD yD / xO yO sx p1 colore)
 (if (> conta 0)
  (progn
   (setq sx (rn sd))
   (setq xM (+ (/ (+ xA xB) 2) sx))
   (setq yM yA)
   (setq xP (- (/ (+ xD xC) 2) sx))
   (setq yP yD)
   (setq xQ (+ xA sx))
   (setq yQ (+ (/ (+ yA yD) 2) sx))
   (setq xN xB)
   (setq yN (- (/ (+ yB yC) 2) sx))
   (setq xO xM)
   (setq yO yQ)
   (setq p1 (list xO yO sx))
   (setq sd sx)
   (cond ; colori random
    ((<= (fix sx)  2)(setq colore 30))
    ((<= (fix sx)  4)(setq colore 31))
    ((<= (fix sx)  6)(setq colore 32))
    ((<= (fix sx)  8)(setq colore 33))
    ((<= (fix sx) 10)(setq colore 41))
    ((<= (fix sx) 13)(setq colore 255)) ; bianco
   )
   (command "_color" colore)
   (if (= colore 255)
    (command "_sphere" p1 0.1) ; zucchero
    (command "_sphere" p1 1)   ; riso
   )
   (frittella (- conta 1) xA yA xM yM xO yO xQ yQ)
   (frittella (- conta 1) xM yM xB yB xN yN xO yO)
   (frittella (- conta 1) xO yO xN yN xC yC xP yP)
   (frittella (- conta 1) xQ yQ xO yO xP yP xD yD)
  )
 )
)

(defun C:FRTR (/  olderr orto snapp snm piano)
 (setq olderr  *error*  *error* myerror)
 (setvar "cmdecho" 0)
 (salVar)
 (setq sd 0.0)
 (initget (+ 2 4))
 ; tenersi bassi con i giri!
 (setq conta (getint "\nNumero di giri [6]: "))
 (if (= conta nil)(setq conta 6))

 ;| disegna il quadrato

     D-----------C
     |           |
     |           |
     |           |
     |           |
     A-----------B
 |;
 (setq xA 0)
 (setq yA 0)
 (setq xB 0.1)
 (setq yB 0) 
 (setq xC 0.1)
 (setq yC 0.1) 
 (setq xD 0)
 (setq yD 0.1) 

 (command "_osnap" "_non")

 (frittella conta xA yA xB yB xC yC xD yD)

 (command "_zoom" "_all")

 (ripVar)
)
;;;eof
frtr.lsp

Come si vede il risultato non è proprio una frittella! Una frittella deve rimanere compatta (al contrario di una nuvola) cioè deve avere una forma a... frittella.
Ho modificato il sorgente in vari punti (i righi modificati sono in blu).

;;;
;;;    frtr.lsp v1.1 - 21 Febbraio 2004
;;;    (C) 2004 by Claudio Piccini.
;;;    www.cg-cad.com
;;;    
;;;    Disegna una frittella di riso con zucchero 3D.
;;;

(defun myerror (s)                  
  (if (/= s "Function cancelled")
    (princ (strcat "\nError: " s))
  )
 (ripVar)
 (princ)
)

(defun salVar ()
 (setq orto (getvar "orthomode"))
 (setq snapp (getvar "osmode"))
 (setq snm (getvar "snapmode"))
 (setq piano (getvar "clayer"))
)

(defun ripVar ()
 (setvar "cmdecho" 1)
 (setvar "osmode" snapp)
 (setvar "snapmode" snm)
 (setvar "orthomode" orto)
 (setvar "clayer" piano)
 (setvar "cecolor" "BYLAYER")
 (setq *error* olderr)
 (princ)
)

; numeri casuali
(defun rn (sd)
 (setq m 65521 b 15937 c 33503 sd 
  (rem (+ (* b sd) c) m)
 )
 (* (/ sd m) 15)
)

 ;|
     D-----P-----C
     |           |
     |           |
     Q     O     N
     |           |
     |           |
     A-----M-----B
 |;

(defun frittella (conta xA yA xB yB xC yC xD yD / xO yO sx p1 colore)
 (if (> conta 0)
  (progn
   (setq sx (rn sd))
   (setq xM (+ (/ (+ xA xB) 2) sx))
   (setq yM yA)
   (setq xP (- (/ (+ xD xC) 2) sx))
   (setq yP yD)
   (setq xQ (+ xA sx))
   (setq yQ (+ (/ (+ yA yD) 2) sx))
   (setq xN xB)
   (setq yN (- (/ (+ yB yC) 2) sx))
   (setq xO xM)
   (setq yO yQ)
   (setq p1 (list xO yO sx))
   (setq sd sx)
   (cond ; colori random
    ((<= (fix sx)  2)(setq colore 51))
    ((<= (fix sx)  6)(setq colore 31))
    ((<= (fix sx)  8)(setq colore 33))
    ((<= (fix sx) 10)(setq colore 41))
    ((<= (fix sx) 14)(setq colore 255)) ; bianco
   )
   (command "_color" colore)
   (if (= colore 255)
    (command "_sphere" p1 0.3) ; zucchero
    (command "_sphere" p1 12)   ; riso
   )
   (frittella (- conta 1) xA yA xM yM xO yO xQ yQ)
   (frittella (- conta 1) xM yM xB yB xN yN xO yO)
   (frittella (- conta 1) xO yO xN yN xC yC xP yP)
   (frittella (- conta 1) xQ yQ xO yO xP yP xD yD)
  )
 )
)

(defun C:FRTR (/  olderr orto snapp snm piano)
 (setq olderr  *error*  *error* myerror)
 (setvar "cmdecho" 0)
 (salVar)
 (setq sd 0.0)
 (initget (+ 2 4))
 ; tenersi bassi con i giri!
 (setq conta (getint "\nNumero di giri [6]: "))
 (if (= conta nil)(setq conta 6))

 ;| disegna il quadrato

     D-----------C
     |           |
     |           |
     |           |
     |           |
     A-----------B
 |;
 (setq xA 0)
 (setq yA 0)
 (setq xB 0.1)
 (setq yB 0) 
 (setq xC 0.1)
 (setq yC 0.1) 
 (setq xD 0)
 (setq yD 0.1) 

 (command "_osnap" "_non")

 (frittella conta xA yA xB yB xC yC xD yD)

 (command "_zoom" "_all")

 (ripVar)
)
;;;eof

frtr.lsp: seconda versione frtr.lsp: seconda versione

Tempi di cottura

Lupo Alberto © SilverSupponete di avere una coppia di conigli cuccioli...
"Una coppia di conigli fu posta in un recinto per determinare quanti conigli potevano essere prodotti da questa coppia in un anno, supponendo che ogni mese ogni coppia ne crei un'altra, la quale nel secondo mese diventa produttiva."
Questo problema se lo poneva nel 1228 Leonardo Pisano figlio di Bonaccio detto Fibonacci che così spiega la soluzione:
"Poiché la prima coppia ha figliato nel primo mese, il numero raddoppia, e nel primo mese si hanno due coppie. Di queste, una coppia, la prima, figlia nel secondo mese in modo che alla fine del suddetto mese le coppie di conigli sono tre..."
E così scoprendo la successione 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... dove ogni numero si ottiene sommando i due immediatamente precedenti.
f(0)=f(1)=1;
f(s)=f(s-1) + f(s-2), s>=2

Implementare in Lisp la successione con le funzioni ricorsive è facile:

(defun fibo (n)
 (if (<= n 1) 
  (setq nc 1)
  (setq nc (+ (fibo (- n 1))(fibo (- n 2))))
 )
)

(defun c:fibon ()
 (initget (+ 1 4)) ; non nullo e non negativo
 (setq n (getint "\nIntrodurre un numero: "))
 (princ (strcat "\nLe coppie sono: " (itoa (fibo n))))
 (princ)
)

Ma nel lisp il numero di chiamate per calcolare fibo(n) è dato dalla somma tra il numero di chiamate necessarie a calcolare fibo(n-1) ed il numero di chiamate necessarie a calcolare fibo(n-2).
fibo(n)=f(s): il tempo di cottura è un tempo esponenziale.
Ecco un'alternativa:

;;;
;;;    fibo.lsp - 21 Febbraio 2004
;;;    (C) 2004 by Claudio Piccini.
;;;    www.cg-cad.com
;;;    
;;;    Salva (in un secondo) nella lista ls 
;;;    i primi 31 numeri di Fibonacci.
;;;
(defun c:fibo (/ max i a b fibo)
 (setq max 30)
 (setq i 2)
 (setq a 1)
 (setq b 1)
 (setq ls (list a b))
 (while (<= i max)
  (setq fibo (+ a b))
  (setq ls (append ls (list fibo)))
  (setq a b)
  (setq b fibo)
  (setq i (1+ i))
 )
 (princ)
)
;;;eof

Command: fibo

Command: !ls
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269)

Provate i tempi di cottura dei due lisp...

Lisp »Tips 'n Tricks

Ultimo Aggiornamento_Last Update: 21 Febbraio 2004