cg-Cad

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

DORB.LSP
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

DORB.LSP
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

DORB.LSP
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