Lisp »Tips 'n Tricks 
»Funzioni ricorsive in AutoLISP
 »1
 | 2
 | 3
 | 4
 | 5
 | 6
 | 7 a
 , b
 , c
 , d
 , e
 >II
 >III
 >IV
 >V
 >VI
 >VII 
Diagramma delle orbite 
DORB disegna il diagramma delle orbite di f(x)=x²+c con a<=c<=b.
 L'algoritmo di base (in Basic) è il seguente: 
FOR C = -2 TO 0.25 STEP 0.00625
   X = 0
   M = 160*(C+2)
   FOR I = 0 TO 200
      X = X*X+C
      IF I<50 GOTO 11
      N = 75*(2-X)
      PSET(M,N)
   11 NEXT I
NEXT C
END
Da: "Caos e frattali", R.L. Devaney. Editore Addison-Wesley Masson 
Il lisp chiede il valore di x e il valore minimo (a) e massimo (b) di c e poi calcola i passi (step) dividendo i valori assoluti di a e b per 360. 
;;;
;;;    Dorb.lsp - 28 Marzo 2004
;;;    (C) 2004 by Claudio Piccini.
;;;    www.cg-cad.com
;;;    
;;;    Disegna il diagramma delle orbite
;;;    di f(x) = x2 + c con a<=c<=b
;;;
(defun itera ( x c / i y M N )
 (if (<= c b)
  (progn
   (setq x x0)
   (setq M (* K (+ c (abs a))))
   (setq i 0)
   (while (< i 200)
    (setq y (+ (* x x) c))
    (if (> i 50)
     (progn
      (setq N (* 75 (+ 2 y)))
      (command "_point" (list M N 0))
     )
    )
    (setq i (1+ i))
    (setq x y)
   )
   (itera x (+ c step))
  )
 )
)
(defun c:dorb ( / a b step K x0 )
 (setvar "cmdecho" 0)
 (setq snapp (getvar "osmode"))
 (command "_osnap" "_non")
 (initget 2) ;non zero
 (setq a (getreal "\nValore minimo di c [-2.0]: "))
 (if (= a nil)
  (setq a -2.0)
 )
 (initget 2) ;non zero
 (setq b (getreal "\nValore massimo di c [0.25]: "))
 (if (= b nil)
  (setq b 0.25)
 )
 ;
 ; calcola il passo: step
 ; e la costante di trasformazione: K
 ;
 (cond 
  ((and (> a 0)(> b 0))
   (setq step (/ (- b a) 360.0))
   (setq K (/ 360 (- b a)))
  )
  ((and (< a 0)(< b 0))
   (setq step (/ (- (abs a)(abs b)) 360.0))
   (setq K (/ 360 (- (abs a)(abs b))))
  )
  (T
   (setq step (/ (+ (abs a)(abs b)) 360.0))
   (setq K (/ 360 (+ (abs a)(abs b))))
  )
 )
 (princ (strcat "\nstep=" (rtos step 2 6)))
 ;
 ; chiede il valore di x
 ;
 (setq x0 (getreal "\nNumero? "))
 ;
 ; chiama la funzione
 ;
 (itera x0 a)
 (setvar "osmode" snapp)
 (command "_redraw")
 (setvar "cmdecho" 1)
 (princ)
)
;;;eof
 |   
Test del LISP 
Command: dorb
 Valore minimo di c [-2.0]: Invio
 Valore massimo di c [0.25]: Invio
 step=0.00625
 Numero? 0 
 
 Clicca sull'immagine per ingrandire. 
  
Le linee verticali nel diagramma rappresentano la dinamica di una singola orbita, cioè le 200 iterazioni di f(x) meno le prime 50 (per mostrare il comportamento asintotico dell'orbita).
 Se su una linea verticale del diagramma compaiono pochi punti significa che il valore iniziale di x è stato attirato in un ciclo.
 Intervenendo sui valori di c il lisp permette di zoomare e stretchare il diagramma mettendo in evidenza la struttura fine delle zone caotiche e della soglia di passaggio ai cicli. 
Valore minimo di c [-2.0]: -1.65
 Valore massimo di c [0.25]: -0.75
 step=0.0025
 Numero? 0 
 
 Clicca sull'immagine per ingrandire. 
  
Command: dorb
 Valore minimo di c [-2.0]: -1.8
 Valore massimo di c [0.25]: -1.725
 step=0.000208
 Numero? 0 
 
 Nel caos si apre una finestra di periodo 3.
 Clicca sull'immagine per ingrandire. 
  
Analisi del LISP 
Il sorgente in Basic nasce per la grafica bitmap e si basa su uno schermo grafico di 300 per 300 pixel, per semplificare la traduzione in lisp ho mantenuto tale vincolo, ho solo cambiato il segno nella formula da N=75*(2-x) in (setq N (* 75 (+ 2 y))) per evitare di disegnare il diagramma capovolto.
 L'asse verticale y dello schermo grafico in pixel è diretto in verso opposto rispetto al piano cartesiano (x,y) cioè dall'alto verso il basso.
 Le formule di trasformazione per 300x300 sono M=300*(x-l)/(r-l) e N=300*(r-y)/(r-l) nel sorgente in Basic è N=300*(2-y)/(2+2) con un intervallo di -2<c<2 e quindi 75*(2-y), ho lasciato il valore 75 per semplificare e poi perché non cambia l'output.
 Le coordinate dello schermo sono (M,N) quindi ogni pixel è disegnato dal comando Basic PSET(M,N) che nel lisp diventa (command "_point" (list M N 0))
 
 All'interno dell'intervallo il lisp funziona al di fuori va sperimentato così come con altre funzioni, ad esempio cx(1-x) e nel caso o si sostituisce la formula manualmente nel sorgente o si inserisce un input prendendo a modello il lisp ITRG. 
Lisp »Tips 'n Tricks 
Ultimo Aggiornamento_Last Update: 29 Marzo 2004 
 |