Lisp »Tips 'n Tricks
»Simmetrie »1 »2 »3 »4 »5 »6 »7
SYM1
;|
SYM.LSP (variante 1) (C) 2005 by Claudio Piccini.
www.cg-cad.com
Traduzione in autolisp dell'algoritmo 'Symmetric Network Generator'
in 'Computers, Pattern, Chaos and Beauty' di C.A. Pickover
2001, Dover Publications, Inc.
Pseudocode 10.1:
theta=0; l=0;
do i = 1 to irep /* irep is overall repetition */
do j = 1 to num /* num=number of (angle,length,repeat) sets */
do k = 1 to repeat(j);
l=l+1; /* l is number of vertices in network */
theta=theta+angle(i);
if theta >= 360 then theta=theta-360;
x=length(j)*sin(theta)+x;
y=length(j)*cos(theta)+y;
x_coord(l)=x;
y_coord(l)=y;
end;
end;
end;
|;
(defun sng ( / theta steps
a1 a2 a3 angle
l1 l2 l3 length
r1 r2 r3 rip
x y p0 p1
i j k
)
(setq theta 0
x 0
y 0
)
;|
input 3 angoli
|;
(initget 4) ; non negativo
(setq a1 (getint "\n angolo 1? [30] "))
(if (= a1 nil)(setq a1 30))
(initget 4) ; non negativo
(setq a2 (getint "\n angolo 2? [45] "))
(if (= a2 nil)(setq a2 45))
(initget 4) ; non negativo
(setq a3 (getint "\n angolo 3? [30] "))
(if (= a3 nil)(setq a3 30))
(setq angle (list a1 a2 a3))
;|
input 3 lunghezze
|;
(initget 4) ; non negativo
(setq l1 (getint "\n lunghezza 1? [10] "))
(if (= l1 nil)(setq l1 10))
(initget 4) ; non negativo
(setq l2 (getint "\n lunghezza 2? [5] "))
(if (= l2 nil)(setq l2 5))
(initget 4) ; non negativo
(setq l3 (getint "\n lunghezza 3? [10] "))
(if (= l3 nil)(setq l3 10))
(setq length (list l1 l2 l3))
;|
input 3 cicli
|;
(initget 4) ; non negativo
(setq r1 (getint "\n ciclo 1? [4] "))
(if (= r1 nil)(setq r1 4))
(initget 4) ; non negativo
(setq r2 (getint "\n ciclo 2? [5] "))
(if (= r2 nil)(setq r2 5))
(initget 4) ; non negativo
(setq r3 (getint "\n ciclo 3? [6] "))
(if (= r3 nil)(setq r3 6))
(setq rip (list r1 r2 r3))
;|
input steps
|;
(initget (+ 2 4)) ; non 0 non negativo
(setq steps (getint "\n steps? [100] "))
(if (= steps nil)(setq steps 100))
(setq p0 (getpoint "\n clicca un punto:"))
(setq i 1)
(while (<= i steps)
(setq j 1)
(while (<= j 3)
(setq k 1)
(while (<= k (nth j rip))
(setq theta (+ theta (nth j angle)))
(if (>= theta 360)
(setq theta (- theta 360))
)
(setq x (+ (* (nth j length)(sin (* pi (/ theta 180.0)))) x))
(setq y (+ (* (nth j length)(cos (* pi (/ theta 180.0)))) y))
(setq p1 (list (+ x (car p0))(+ y (cadr p0))))
(command "_point" p1)
(setq k (1+ k))
)
(setq j (1+ j))
)
(setq i (1+ i)
x 0
y 0
)
)
)
(defun c:sym ( / snapp )
(setvar "cmdecho" 0)
(setq snapp (getvar "osmode"))
(command "_osnap" "_non")
(sng)
(setvar "osmode" snapp)
(command "_redraw")
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del lisp (v.1)
Command: sym
angolo 1? [30] 10
angolo 2? [45] 30
angolo 3? [30] 10
lunghezza 1? [10] Invio
lunghezza 2? [5] Invio
lunghezza 3? [10] Invio
ciclo 1? [4] 10
ciclo 2? [5] 11
ciclo 3? [6] 12
steps? [100] Invio
clicca un punto:
Command: sym
angolo 1? [30] 10
angolo 2? [45] 30
angolo 3? [30] 10
lunghezza 1? [10] 20
lunghezza 2? [5] 10
lunghezza 3? [10] 20
ciclo 1? [4] Invio
ciclo 2? [5] 6
ciclo 3? [6] 7
steps? [100] Invio
clicca un punto:
Command: sym
angolo 1? [30] 18
angolo 2? [45] 23
angolo 3? [30] 40
lunghezza 1? [10] Invio
lunghezza 2? [5] Invio
lunghezza 3? [10] Invio
ciclo 1? [4] 10
ciclo 2? [5] 11
ciclo 3? [6] 12
steps? [100] Invio
clicca un punto:
Command: sym
angolo 1? [30] 100
angolo 2? [45] 10
angolo 3? [30] 100
lunghezza 1? [10] Invio
lunghezza 2? [5] Invio
lunghezza 3? [10] Invio
ciclo 1? [4] 10
ciclo 2? [5] 20
ciclo 3? [6] 30
steps? [100] Invio
clicca un punto:
SYM2
In questa variante del lisp le coordinate x,y del punto non sono inizializzate a zero ad ogni ciclo (while (<= i steps) ... ). Le modifiche apportate al sorgente sono in blu.
Per confrontare i due lisp uso gli stessi dati nei test.
;|
SYM2.LSP (C) 2005 by Claudio Piccini.
www.cg-cad.com
Traduzione in autolisp dell'algoritmo 'Symmetric Network Generator'
in 'Computers, Pattern, Chaos and Beauty' di C.A. Pickover
2001, Dover Publications, Inc.
(Pseudocode 10.1)
|;
(defun sng2 ( / theta steps
a1 a2 a3 angle
l1 l2 l3 length
r1 r2 r3 rip
x y p0 p1
i j k
)
(setq theta 0
x 0
y 0
)
;|
input 3 angoli
|;
(initget 4) ; non negativo
(setq a1 (getint "\n angolo 1? [30] "))
(if (= a1 nil)(setq a1 30))
(initget 4) ; non negativo
(setq a2 (getint "\n angolo 2? [45] "))
(if (= a2 nil)(setq a2 45))
(initget 4) ; non negativo
(setq a3 (getint "\n angolo 3? [30] "))
(if (= a3 nil)(setq a3 30))
(setq angle (list a1 a2 a3))
;|
input 3 lunghezze
|;
(initget 4) ; non negativo
(setq l1 (getint "\n lunghezza 1? [10] "))
(if (= l1 nil)(setq l1 10))
(initget 4) ; non negativo
(setq l2 (getint "\n lunghezza 2? [5] "))
(if (= l2 nil)(setq l2 5))
(initget 4) ; non negativo
(setq l3 (getint "\n lunghezza 3? [10] "))
(if (= l3 nil)(setq l3 10))
(setq length (list l1 l2 l3))
;|
input 3 cicli
|;
(initget 4) ; non negativo
(setq r1 (getint "\n ciclo 1? [4] "))
(if (= r1 nil)(setq r1 4))
(initget 4) ; non negativo
(setq r2 (getint "\n ciclo 2? [5] "))
(if (= r2 nil)(setq r2 5))
(initget 4) ; non negativo
(setq r3 (getint "\n ciclo 3? [6] "))
(if (= r3 nil)(setq r3 6))
(setq rip (list r1 r2 r3))
;|
input steps
|;
(initget (+ 2 4)) ; non 0 non negativo
(setq steps (getint "\n steps? [100] "))
(if (= steps nil)(setq steps 100))
(setq p0 (getpoint "\n clicca un punto:"))
(setq i 1)
(while (<= i steps)
(setq j 1)
(while (<= j 3)
(setq k 1)
(while (<= k (nth j rip))
(setq theta (+ theta (nth j angle)))
(if (>= theta 360)
(setq theta (- theta 360))
)
(setq x (+ (* (nth j length)(sin (* pi (/ theta 180.0)))) x))
(setq y (+ (* (nth j length)(cos (* pi (/ theta 180.0)))) y))
(setq p1 (list (+ x (car p0))(+ y (cadr p0))))
(command "_point" p1)
(setq k (1+ k))
)
(setq j (1+ j))
)
(setq i (1+ i)
; x 0
; y 0
)
)
)
(defun c:sym2 ( / snapp )
(setvar "cmdecho" 0)
(setq snapp (getvar "osmode"))
(command "_osnap" "_non")
(sng2)
(setvar "osmode" snapp)
(command "_redraw")
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del lisp (v.2)
Command: sym2
angolo 1? [30] 10
angolo 2? [45] 30
angolo 3? [30] 10
lunghezza 1? [10] Invio
lunghezza 2? [5] Invio
lunghezza 3? [10] Invio
ciclo 1? [4] 10
ciclo 2? [5] 11
ciclo 3? [6] 12
steps? [100] Invio
clicca un punto:
Command: sym2
angolo 1? [30] 10
angolo 2? [45] 30
angolo 3? [30] 10
lunghezza 1? [10] 20
lunghezza 2? [5] 10
lunghezza 3? [10] 20
ciclo 1? [4] Invio
ciclo 2? [5] 6
ciclo 3? [6] 7
steps? [100] Invio
clicca un punto:
Command: sym2
angolo 1? [30] 18
angolo 2? [45] 23
angolo 3? [30] 40
lunghezza 1? [10] Invio
lunghezza 2? [5] Invio
lunghezza 3? [10] Invio
ciclo 1? [4] 10
ciclo 2? [5] 11
ciclo 3? [6] 12
steps? [100] Invio
clicca un punto:
Command: sym2
angolo 1? [30] 100
angolo 2? [45] 10
angolo 3? [30] 100
lunghezza 1? [10] Invio
lunghezza 2? [5] Invio
lunghezza 3? [10] Invio
ciclo 1? [4] 10
ciclo 2? [5] 20
ciclo 3? [6] 30
steps? [100] Invio
clicca un punto:
SYM3
Questo lisp (una variante di SYM1 cioè con x=0, y=0) mostra come utilizzare le funzioni ricorsive in autolisp.
L'esempio presenta una situazione in cui il programma termina (stop con nc=0), se non è presente uno stop la funzione invoca sé stessa all'infinito cioè una funzione ricorsiva non può essere definita esclusivamente in termini di sé stessa, altrimenti darebbe luogo ad una definizione circolare; quindi una caratteristica essenziale in una definizione ricorsiva è data dalla condizione di terminazione, il cui scopo consiste nel determinare quando una funzione non deve più essere definita in termini di sé stessa.
;|
SYM3.LSP (C) 2005 by Claudio Piccini.
www.cg-cad.com
Traduzione in autolisp dell'algoritmo 'Symmetric Network Generator'
in 'Computers, Pattern, Chaos and Beauty' di C.A. Pickover
2001, Dover Publications, Inc.
(Pseudocode 10.1)
|;
(defun sng3 ( x y nc / j k p1)
(if (> nc 0)
(progn
(setq j 1)
(while (<= j 3)
(setq k 1)
(while (<= k (nth j rip))
(setq theta (+ theta (nth j angle)))
(if (>= theta 360)(setq theta (- theta 360)))
(setq x (+ (* (nth j length)(sin (* pi (/ theta 180.0)))) x))
(setq y (+ (* (nth j length)(cos (* pi (/ theta 180.0)))) y))
(setq p1 (list (+ x (car p0))(+ y (cadr p0))))
(command "_point" p1)
(setq k (1+ k))
)
(setq j (1+ j))
)
(setq nc (sng3 0 0 (1- nc)))
)
)
)
(defun c:sym3 ( / snapp
theta steps
a1 a2 a3 angle
l1 l2 l3 length
r1 r2 r3 rip
)
(setvar "cmdecho" 0)
(setq snapp (getvar "osmode"))
(command "_osnap" "_non")
(setq theta 0)
;|
input 3 angoli
|;
(initget 4) ; non negativo
(setq a1 (getint "\n angolo 1? [30] "))
(if (= a1 nil)(setq a1 30))
(initget 4) ; non negativo
(setq a2 (getint "\n angolo 2? [45] "))
(if (= a2 nil)(setq a2 45))
(initget 4) ; non negativo
(setq a3 (getint "\n angolo 3? [30] "))
(if (= a3 nil)(setq a3 30))
(setq angle (list a1 a2 a3))
;|
input 3 lunghezze
|;
(initget 4) ; non negativo
(setq l1 (getint "\n lunghezza 1? [10] "))
(if (= l1 nil)(setq l1 10))
(initget 4) ; non negativo
(setq l2 (getint "\n lunghezza 2? [5] "))
(if (= l2 nil)(setq l2 5))
(initget 4) ; non negativo
(setq l3 (getint "\n lunghezza 3? [10] "))
(if (= l3 nil)(setq l3 10))
(setq length (list l1 l2 l3))
;|
input 3 cicli
|;
(initget 4) ; non negativo
(setq r1 (getint "\n ciclo 1? [4] "))
(if (= r1 nil)(setq r1 4))
(initget 4) ; non negativo
(setq r2 (getint "\n ciclo 2? [5] "))
(if (= r2 nil)(setq r2 5))
(initget 4) ; non negativo
(setq r3 (getint "\n ciclo 3? [6] "))
(if (= r3 nil)(setq r3 6))
(setq rip (list r1 r2 r3))
;|
input steps
|;
(initget (+ 2 4)) ; non 0 non negativo
(setq steps (getint "\n steps? [100] "))
(if (= steps nil)(setq steps 100))
(setq p0 (getpoint "\n clicca un punto:"))
(sng3 0 0 steps)
(setvar "osmode" snapp)
(command "_redraw")
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del lisp
Command: sym3
angolo 1? [30] 100
angolo 2? [45] 10
angolo 3? [30] 100
lunghezza 1? [10] 12
lunghezza 2? [5] Invio
lunghezza 3? [10] 13
ciclo 1? [4] 10
ciclo 2? [5] 20
ciclo 3? [6] 40
steps? [100] Invio
clicca un punto:
SYM4
Disegna una sfera al posto del punto; cancella le entità sovrapposte.
;|
SYM4.LSP (C) 2005 by Claudio Piccini.
www.cg-cad.com
Traduzione in autolisp dell'algoritmo 'Symmetric Network Generator'
in 'Computers, Pattern, Chaos and Beauty' di C.A. Pickover
2001, Dover Publications, Inc.
(Pseudocode 10.1)
|;
(defun sng4 ( x y nc / j k p1)
(if (> nc 0)
(progn
(setq j 1)
(while (<= j 3)
(setq k 1)
(while (<= k (nth j rip))
(setq theta (+ theta (nth j angle)))
(if (>= theta 360)(setq theta (- theta 360)))
(setq x (+ (* (nth j length)(sin (* pi (/ theta 180.0)))) x))
(setq y (+ (* (nth j length)(cos (* pi (/ theta 180.0)))) y))
(setq p1 (list (+ x (car p0))(+ y (cadr p0))))
(command "_erase" p1 "") ; cancella le entita' sovrapposte
(command "_sphere" p1 1) ; disegna una sfera di raggio 1
(setq k (1+ k))
)
(setq j (1+ j))
)
(setq nc (sng4 0 0 (1- nc)))
)
)
)
(defun c:sym4 ( / snapp
theta steps
a1 a2 a3 angle
l1 l2 l3 length
r1 r2 r3 rip
)
(setvar "cmdecho" 0)
(setq snapp (getvar "osmode"))
(command "_osnap" "_non")
(setq theta 0)
;|
input 3 angoli
|;
(initget 4) ; non negativo
(setq a1 (getint "\n angolo 1? [30] "))
(if (= a1 nil)(setq a1 30))
(initget 4) ; non negativo
(setq a2 (getint "\n angolo 2? [45] "))
(if (= a2 nil)(setq a2 45))
(initget 4) ; non negativo
(setq a3 (getint "\n angolo 3? [30] "))
(if (= a3 nil)(setq a3 30))
(setq angle (list a1 a2 a3))
;|
input 3 lunghezze
|;
(initget 4) ; non negativo
(setq l1 (getint "\n lunghezza 1? [10] "))
(if (= l1 nil)(setq l1 10))
(initget 4) ; non negativo
(setq l2 (getint "\n lunghezza 2? [5] "))
(if (= l2 nil)(setq l2 5))
(initget 4) ; non negativo
(setq l3 (getint "\n lunghezza 3? [10] "))
(if (= l3 nil)(setq l3 10))
(setq length (list l1 l2 l3))
;|
input 3 cicli
|;
(initget 4) ; non negativo
(setq r1 (getint "\n ciclo 1? [4] "))
(if (= r1 nil)(setq r1 4))
(initget 4) ; non negativo
(setq r2 (getint "\n ciclo 2? [5] "))
(if (= r2 nil)(setq r2 5))
(initget 4) ; non negativo
(setq r3 (getint "\n ciclo 3? [6] "))
(if (= r3 nil)(setq r3 6))
(setq rip (list r1 r2 r3))
;|
input steps
|;
(initget (+ 2 4)) ; non 0 non negativo
(setq steps (getint "\n steps? [10] "))
(if (= steps nil)(setq steps 10))
(setq p0 (getpoint "\n clicca un punto:"))
(sng4 0 0 steps)
(setvar "osmode" snapp)
(command "_redraw")
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del lisp
Command: sym4
angolo 1? [30] 100
angolo 2? [45] 10
angolo 3? [30] 100
lunghezza 1? [10] 12
lunghezza 2? [5] Invio
lunghezza 3? [10] 13
ciclo 1? [4] 10
ciclo 2? [5] 20
ciclo 3? [6] 40
steps? [10] 5
clicca un punto:
Lisp »Tips 'n Tricks
Ultimo Aggiornamento_Last Update: 17 Aprile 2005
|