cg-Cad

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:

SYM.LSP

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:

SYM.LSP

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:

SYM.LSP

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:

SYM.LSP

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:

SYM2.LSP

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:

SYM2.LSP

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:

SYM2.LSP

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:

SYM2.LSP

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:

SYM3.LSP

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:

SYM4.LSP

Lisp »Tips 'n Tricks

Ultimo Aggiornamento_Last Update: 17 Aprile 2005