Lispowa choinka przykładem użycia generatora liczb losowych

Dziś w przypływie entuzjazmu przedświątecznej atmosfery chciałbym przedstawić funkcję rysującą choinkę. Sama choinka nie jest oczywiście celem, ale na jej przykładzie można pokazać np losowanie liczb, tworzenie bloków, tworzenie polilinii, kreskowania i innych obiektów, manipulację właściwościami obiektów, zbliżanie i oddalanie widoku.

(vl-load-com)

(setq *ZWCAD* (vlax-get-acad-object))
(setq *Rysunek* (vla-get-activedocument *ZWCAD* ))
(setq *Model* (vla-get-Modelspace *Rysunek* ))

(defun l2v (Lpts / )

(vlax-make-variant (vlax-safearray-fill (vlax-make-safearray vlax-vbdouble (cons 0 (1- (length Lpts)))) Lpts ))
)

(defun Nowabombka ( / )
(setq czybombkajuzistnieje (tblsearch "block" "bombka")) ; tblsearch sprawdza czy element o określonej nazwie znajduje się w kolekcji, w tym przypadku sprawdzamy kolekcję bloków, ale równie dobrze może to być kolekcja warstw czy stylów.
(setq bloki (vlax-get-property *Rysunek* 'blocks ) )
(if czybombkajuzistnieje
(progn
(setq bombka(vlax-invoke-method bloki 'Item "bombka"))
)
(progn
(setq bombka(vlax-invoke-method bloki 'Add (vlax-3d-point (list 0 0 0 ) ) "bombka" ) ) ; tworzenie nowego bloku
(setq kolko(vlax-invoke-method bombka 'AddCircle (vlax-3d-point (list 0 0 0 ) ) 1 )) ; tworzenie okręgu w bloku
(vlax-put-property kolko 'Color 0 )
(setq wypelnienie(vlax-invoke-method bombka 'AddHatch zcHatchPatternTypePreDefined "SOLID" t )) ; tworzenie kreskowania a bloku
(setq ObrysSA (vlax-make-safearray vlax-vbobject '(0 . 0) ))
(vlax-safearray-fill ObrysSA (list kolko ))
(vlax-invoke-method wypelnienie 'AppendOuterLoop ObrysSA )
(vlax-invoke-method wypelnienie 'Evaluate )
(vlax-put-property wypelnienie 'Color 0 )

))
)

(defun wstawbombke (x y / kolorbombki wielkosc bPx nowabombka )

(setq kolorbombki (rand (rand 0 100) (rand 50 256))) ; losujemy kolor z zakresu, który również jest losowany
(setq wielkosc (rand (rand 2 5 ) (rand 2 5))) ; wielkość również losujemy
(setq bPx (vlax-3d-point (list (rand (* -0.7 x) (* 0.7 x) ) (+ y (rand -3 3 ) ))))
(setq nowabombka(vlax-invoke-method *Model* 'InsertBlock bPx "bombka" wielkosc wielkosc wielkosc 0 )) ; wstawienie bloku
(vlax-put-property nowabombka 'Color kolorbombki )

)
(defun rand (start stop / # seed tmp) ; generator liczb pseudolosowych. Niestety LISP nie ma wbudowanej funkcji losującej liczby , więc musimy posłużyc sie czymś co jest najbardziej zbliżone do losowania, w tym przypadku będzie to czas systemowy zmieniający się z każdą milisekundą.
; w Internecie można znaleźć kilka różnych funkcji losujących. Połączyłem dwie z nich by móc określać zakres losowania liczb.

(if (not seed) (setq seed (- (setq tmp (getvar "DATE")) (fix tmp))) )
(setq seed (- (setq tmp (/ (* seed 1000000000 663608941) 1000000000.0)) ; generowanie liczb pseudolosowych
(fix tmp)))

(+ start (* (- stop start) seed ) ) ; liczba pseudolosowa jest przeliczana by zawierała się w zadanym zakresie.

)

(defun C:choinka ( / punkty )

(setq cnt 10 )
(setq H 250.0 )
;(setq x 100 )
(setq x 10 )
(setq y ( / H cnt) )
(setq i 0)
(setq znak 1 )
(setq wciecie -10 )
;(setq punkty (list 0 0 ))
(setq punkty (append punkty (list 0 (+ H 30) ) ) )

(Nowabombka) ; definiujemy najprostszą bombkę, czyli kolorowe kółko.

(repeat cnt
(setq teny (- H (* y i))) ; obliczamy wysokość

(setq punkty (append (list (* 0.6 (+ x (rand -5 5))) teny (+ x (rand -5 5)) teny ) ;
punkty ; Obliczamy współrzędną X "gałęzi" choinki,
(list (- (+ x (rand -5 5)) ) teny (* -0.6 (+ x (rand -5 5))) teny ) ; które również są nieregularne przez
)) ; dodanie losowania współrzędnych w określonym zakresie.

(setq i (1+ i))
(setq znak (* -1 znak) )
(setq x (+ x 10))

(if (and (> teny 1) (< teny H))(progn
(wstawbombke x teny)
(wstawbombke x (* 1.12 teny))
(wstawbombke x (* 1.06 teny))
(wstawbombke x (* 0.92 teny))
(wstawbombke x (* 0.95 teny))
(wstawbombke x (* 1.12 teny))
))
)


;(setq punkty (append punkty revPt) )
(setq choinka (vlax-invoke-method *Model* 'AddLightweightPolyline (l2v punkty))) ; rysowanie samego obrysu naszej choinki
(vlax-put-property choinka 'closed :vlax-true )
(vlax-put-property choinka 'color 3 )

 

(command "_zoom" "_ob" (vlax-vla-object->ename choinka) "") ; zbliżenie widoku, by obejmował całą choinkę
(command "_zoom" "0.8" )

)

Wykonanie w ZWCAD 2015+ LISP Choinka 2015

Wykonanie w ZWCAD ClassicLISP Choinka Classic