wedzik

Użytkownik forum
  • Postów

    46
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    1

Odpowiedzi opublikowane przez wedzik

  1. Zawsze zastanawiałem się dlaczego w niektórych lispach jest taka konstrukcja z kropką

    ._circle

    Winne temu jest polecenie UNDEFINE, które potrafi wyłączyć polecenie cada.

    Jeśli użyjemy wtedy _circle to nie będzie takiego polecenia. Natomiast polecenie z kropką ignoruje UNDEFINE i korzysta z oryginalnych poleceń.

    Polecenie: _CIRCLE
    Określ środek okręgu lub [3P/2P/Ssr (sty sty promień)]: *Anuluj*
    Polecenie: undefine
    Podaj nazwę polecenia:circle
    Polecenie: _CIRCLE
    Nieznane polecenie "_CIRCLE". Naciśnij F1, aby uzyskać pomoc.
    Polecenie: ._CIRCLE
    Określ środek okręgu lub [3P/2P/Ssr (sty sty promień)]: *Anuluj*

     

  2. 1 godzinę temu, BKW napisał:

    Te nie zaznaczone fioletem rozchodzą się promieniście, a te w obwódkach równolegle, a powinny wszystkie tak samo, promieniście

    Chyba bardziej czytelnie jest jak przy małych kątach i dużych promieniach linie pomocnicze są równoległe.

    Przykład z książki - Poradnik Mechanika tom II.

    wymiar-luku.thumb.png.ae38baffa27f7d5dd4d14780be86bba1.png

     

    Zresztą w Autocadzie też tak jest (a przynajmniej było z tego co pamiętam).

     

     

  3. Dzięki pomocy tutaj 

    zrobiłem lispa do zaznaczania okręgów większych niż wpisany promień.

    Na początku jest mechanizm zapamiętywania promienia okręgu. Jeśli nie jest ustawiony to przyjmuję 10.

    (defun c:okregi (/ ile zbior rtemp)
    	(if (= malypromien nil)(setq malypromien 10.0))
    	(prompt "\Podaj maly promien: <")(princ malypromien)(princ "> ")
    	(initget 4)
    	(setq rtemp (getreal)) 
    	(if (= rtemp nil)(setq rtemp malypromien))
    	(setq malypromien rtemp)
    	
    	(setq zbior (ssget "X" (list (cons 0 "CIRCLE") (cons 410 "Model")(cons -4 ">=") (cons 40 malypromien ) ) ))
    	(if zbior (princ (list "Ilosc znalezionych elementow: " (setq ile (sslength zbior)))) (princ "\nBrak elementow"))
    	(if zbior (command "_pselect" "_p" ""))
    	(princ)
    )

     

  4. Dziękuję.

    Oto kod jaki mam teraz. Wyświetla się też komunikat o ilości znalezionych elementów.

    (defun c:okregi (/)
    	(setq malypromien (getreal "Podaj maly promien: ")) 
    	(setq zbior (ssget "X" (list (cons 0 "CIRCLE") (cons 410 "Model")(cons -4 ">=") (cons 40 malypromien ) ) ))
    	(if zbior (princ (list "Ilosc znalezionych elementow: " (setq ile (sslength zbior)))) (princ "\nBrak elementow"))
        (princ)
    )

    Dziwi mnie że te obiekty nie są wybrane na rysunku.

    Można je ręcznie zaznaczyć z linii poleceń tak

    Polecenie: !ile
    47 
    Polecenie: _SELECT
    Wybierz obiekty: _p
    znaleziono 47
    Wybierz obiekty: 

    i po enterze są zaznaczone z gripami.

    Jak to robię w lispie to nic się nie dzieje:

    (command "_select" "_p" "")

    Jak zaznaczyć z lispa na ekranie te elementy ze zbioru "ile" albo ostatnie zaznaczone?

  5. Chcę napisać lispa który zaznaczy mi okręgi o średnicach znajdujących się w przedziale.

    Zacząłem od napisania takiego programu, który zaznacza wszystkie okręgi w rysunku o promieniu większym lub równym od podanego.

    Ten skrypt działa ale muszę wpisać promień wewnątrz skryptu czyli tak (40 . 10 ) - zaznacza okręgi o promieniu >=10

    Cytuj

    (defun c:okregi (/)
        ;(setq malypromien (getreal "Podaj maly promien: ")) 
        (setq zbior (ssget "X" '( (0 . "CIRCLE") (410 . "Model")(-4 . ">=") (40 . 10 ) ) ))
        (setq ile (sslength zbior))
    )

    Jeśli jednak zapytam o promień i zmodyfikuję program to dostanę błąd

    Cytuj

    (defun c:okregi (/)
        (setq malypromien (getreal "Podaj maly promien: ")) 
        (setq zbior (ssget "X" '( (0 . "CIRCLE") (410 . "Model")(-4 . ">=") (40 . malypromien ) ) ))
        (setq ile (sslength zbior))
    )
     

    Cytuj

    Polecenie: OKREGI
    Podaj maly promien: 10
    błąd: nieprawidłowy typ - nil

    Doszukałem, że trzeba zamienić (40 . malypromien ) na (cons 40 malypromien ) ale błąd jest dalej.

    Jakieś sugestie?

  6. Abs nie wystarczył, trzeba było dorzucić IFa.

    Działa już po lewej i po prawej kierunek zaznaczania bez znaczenia.

    (defun c:krawedzieotworux ()
    	(princ "Zaznacz okregi do rzutownia: \n")
    	(setq okrag (ssget  '((0 . "CIRCLE")) )) 		;prosimy o wskazanie obiektów oknem. Pozwalamy na wybor tylko okregow
    	(setq ile (sslength okrag)) 					;liczymy ile obiektow zaznaczylismy
    	(setq i 0) 										;ustawiamy zmienna i zeby sobie odliczac
    	(setq pt1 (getpoint "Wskaz poczatek linii: ")) 
    	(setq pt2 (getpoint "Wskaz koniec linii: ")) 
    	(setq przedluzenieosi (* (abs (- (car pt2) (car pt1) ))  0.1 ))
    	(setq aktualnawarstwa (getvar "CLAYER"))
    	(command "_-LAYER" "_M" "osie" "_C" "red" "" "_L" "CENTER" "" "") ; Tworze warstwe dla osi
    	(repeat ile	 									; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  		; ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  ;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(setq promien (assoc 40 listaobiektu)) 		;odczytujemy promień aktualnego okregu np. (40 . 27.7815)
    		(setq srodek (assoc 10 listaobiektu)) 		;odczytujemy srodek okregu np. (10 310.596 514.272 0.0) 
    		(setq r (cdr promien)) 						;przypisuje do r promien np. 27.7815
    		(setq y (cadr(cdr srodek))) 				;przypisuje do y wspolrzedna Y np. 514.272
    		(setq x (cadr srodek)) 				        ;przypisuje do x wspolrzedna Y np. 310.596
    		(setq grupa (ssadd))
    		(command "_-LAYER" "_S" aktualnawarstwa "")
    		(command "_line" (list (car pt1) (+ y r))  (list (car pt2) (+ y r)) "") ;rysuje linie car pobiera wspolrzedna X z kliknietych punktow
    		(ssadd (entlast) grupa)
    		(command "_line" (list (car pt1) (- y r))  (list (car pt2) (- y r)) "") 
    		(ssadd (entlast) grupa)
    		(command "_-LAYER" "_S" "osie" "")
    		
    		(if (< (car pt1) (car pt2))
    				(command "_line" (list (- (car pt1) przedluzenieosi) y )       (list (+ (car pt2) przedluzenieosi) y) "") ;rysujemy osie symetrii otworów z boku
    				(command "_line" (list (- (car pt2) przedluzenieosi) y )       (list (+ (car pt1) przedluzenieosi) y) "") ;rysujemy osie symetrii otworów z boku
    		)
    		(ssadd (entlast) grupa)
    		;osie na otworach w widoku z góry, na początku os X potem Y
    		(command "_line" (list (- x r przedluzenieosi) y) (list (+ x r przedluzenieosi) y) "" )
    		(ssadd (entlast) grupa)
    		(command "_line" (list x (- y r przedluzenieosi) ) (list x (+ y r przedluzenieosi) ) "" )
    		(ssadd (entlast) grupa)
    		(command "_group" "_c" "*" "opis" grupa "")
    		(setq i (1+ i)) 							;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	(command "_-LAYER" "_S" aktualnawarstwa "")
    	)
    	

     

  7. Kolejna wersja programu: rysuje osie i grupuje elementy otworu.

    Przed

    1278865376_2020-11-2918_58_16-ZWCAD2021Wersjatestowa(Pozostao20dni)-C__Users_jaros_Desktop_krawedzie.png.8e5825bd4658cd0181ade643c4d5d2cb.png

    Po

    1844186092_2020-11-2918_59_13-ZWCAD2021Wersjatestowa(Pozostao20dni)-C__Users_jaros_Desktop_krawedzie.png.f070b072ea1061324f130546a9844b76.png

    (defun c:krawedzieotworux ()
    	(princ "Zaznacz okregi do rzutownia: \n")
    	(setq okrag (ssget  '((0 . "CIRCLE")) )) 			;prosimy o wskazanie obiektów oknem. Pozwalamy na wybor tylko okregow
    	(setq ile (sslength okrag)) 						;liczymy ile obiektow zaznaczylismy
    	(setq i 0) 											;ustawiamy zmienna i zeby sobie odliczac
    	(setq pt1 (getpoint "Wskaz poczatek linii: ")) 
    	(setq pt2 (getpoint "Wskaz koniec linii: ")) 
    	(setq przedluzenieosi (* (- (car pt2) (car pt1) )  0.1 ))
    	(setq aktualnawarstwa (getvar "CLAYER"))
    	(command "_-LAYER" "_M" "osie" "_C" "red" "" "_L" "CENTER" "" "") ; Tworze warstwe dla osi
    	(repeat ile	 						; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  			;ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  	;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(setq promien (assoc 40 listaobiektu)) 			;odczytujemy promień aktualnego okregu np. (40 . 27.7815)
    		(setq srodek (assoc 10 listaobiektu)) 			;odczytujemy srodek okregu np. (10 310.596 514.272 0.0) 
    		(setq r (cdr promien)) 							;przypisuje do r promien np. 27.7815
    		(setq y (cadr(cdr srodek))) 					;przypisuje do y wspolrzedna Y np. 514.272
    		(setq x (cadr srodek)) 				        	;przypisuje do x wspolrzedna Y np. 310.596
    		(setq grupa (ssadd))
    		(command "_-LAYER" "_S" aktualnawarstwa "")
    		(command "_line" (list (car pt1) (+ y r))  (list (car pt2) (+ y r)) "") ;rysuje linie car pobiera wspolrzedna X z kliknietych punktow
    		(ssadd (entlast) grupa)
    		(command "_line" (list (car pt1) (- y r))  (list (car pt2) (- y r)) "") 
    		(ssadd (entlast) grupa)
    		(command "_-LAYER" "_S" "osie" "")
    		(command "_line" (list (- (car pt1) przedluzenieosi) y )       (list (+ (car pt2) przedluzenieosi) y) "") ;rysujemy osie symetrii otworów z boku
    		(ssadd (entlast) grupa)
    		;osie na otworach w widoku z góry, na początku os X potem Y
    		(command "_line" (list (- x r przedluzenieosi) y) (list (+ x r przedluzenieosi) y) "" )
    		(ssadd (entlast) grupa)
    		(command "_line" (list x (- y r przedluzenieosi) ) (list x (+ y r przedluzenieosi) ) "" )
    		(ssadd (entlast) grupa)
    		(command "_group" "_c" "*" "opis" grupa "")
    		(setq i (1+ i)) 								;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	(command "_-LAYER" "_S" aktualnawarstwa "")
    	)
    	

     

    krawedzieotworux1.lsp

  8. Teraz coś co działa. Program do tworzenia krawędzi otworów na drugim rzucie. Wybieramy wszystkie obiekty, odfiltrują się otwory. Wskazujemy gdzie maja się zaczynać i kończyć otwory.

    Na rysunku po lewej przed rzutowaniem po prawej po rzutowaniu. Jak ktoś jest chętny to plik dwg jest tutaj rzutownie-otworow.dwg

    rzutowanie.png.445e6ecbadf699bd712e34d90ff7c140.png

    Plik lispa z opisem krawedzieotworux.lsp

    Teraz pochwalę się moim kodem:

    (defun c:krawedzieotworux ()
    	(princ "Zaznacz okregi do rzutownia: \n")
    	(setq okrag (ssget  '((0 . "CIRCLE")) )) 		;prosimy o wskazanie obiektów oknem. Pozwalamy na wybor tylko okregow
    	(setq ile (sslength okrag)) 				;liczymy ile obiektow zaznaczylismy
    	(setq i 0) 						;ustawiamy zmienna i zeby sobie odliczac
    	(setq pt1 (getpoint "Wskaz poczatek linii: ")) 
    	(setq pt2 (getpoint "Wskaz koniec linii: ")) 
    	(repeat ile	 					; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  		; ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  	;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(setq promien (assoc 40 listaobiektu)) 		;odczytujemy promień aktualnego okregu np. (40 . 27.7815)
    		(setq srodek (assoc 10 listaobiektu)) 		;odczytujemy srodek okregu np. (10 310.596 514.272 0.0) 
    		(setq r (cdr promien)) 				;przypisuje do r promien np. 27.7815
    		(setq y (cadr(cdr srodek))) 			;przypisuje do y wspolrzedna Y np. 514.272
    		(command "_line" (list (car pt1) (+ y r))  (list (car pt2) (+ y r)) "") ;rysuje linie car pobiera wspolrzedna X z kliknietych punktow
    		(command "_line" (list (car pt1) (- y r))  (list (car pt2) (- y r)) "") 
    		(setq i (1+ i)) 				;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	)
    	

     

  9. Dzięki, przyda się.

    Teraz pracuję nad czymś dużym.

    Zrobiłem początek: zapytanie o zaznaczenie obiektów i wyświetlenie liczby zaznaczonych obiektów i ich właściwości.

    (defun c:krawedzie ()
    	(setq okrag (ssget)) ;prosimy o wskazanie obiektów oknem
    	(setq ile (sslength okrag)) ;liczymy ile obiektow zaznaczylismy
    	(setq i 0) ; ustawiamy zmienna i zeby sobie odliczac
    	(repeat ile	 ; powtarzamy tyle razy ile jest obiektow
    		(setq nazwyobiektow (ssname okrag i))  ; ustalamy nazwe kolejnych obiektow
    		(setq listaobiektu (entget nazwyobiektow))  ;pobieramy wlasciwosci obiektu o nazwie jak w lini wyzej
    		(prompt "Obiekt")	;
    		(princ nazwyobiektow) ;drukujemy nazwe obiektu
    		(princ listaobiektu) ; drukujemy wlasciwosci obiektu
    		(setq i (1+ i)) ;zwiekszamy zmienna i aby odczytac kolejny obiekt
    		)
    	)

    W wyniku działania otrzymujemy np. taką listę 

    Wskaż drugi narożnik: 
    znaleziono 7
    Wybierz obiekty: 
    Obiekt<ENTITY NAME: 9d2fc8a8>((-1 . <ENTITY NAME: 9d2fc8a8>) (0 . LWPOLYLINE) (5 . 240) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbPolyline) (90 . 4) (70 . 1) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 253.739 563.116) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 541.421 563.116) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 541.421 398.539) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 253.739 398.539) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc890>((-1 . <ENTITY NAME: 9d2fc890>) (0 . CIRCLE) (5 . 23F) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 494.711 459.655 0.0) (40 . 28.7788) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc878>((-1 . <ENTITY NAME: 9d2fc878>) (0 . CIRCLE) (5 . 23E) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 461.97 514.66 0.0) (40 . 29.5208) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc860>((-1 . <ENTITY NAME: 9d2fc860>) (0 . CIRCLE) (5 . 23D) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 419.625 450.488 0.0) (40 . 24.386) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc848>((-1 . <ENTITY NAME: 9d2fc848>) (0 . CIRCLE) (5 . 23C) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 337.992 440.884 0.0) (40 . 22.7003) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc830>((-1 . <ENTITY NAME: 9d2fc830>) (0 . CIRCLE) (5 . 23B) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 380.773 504.183 0.0) (40 . 21.6078) (210 0.0 0.0 1.0))
    Obiekt<ENTITY NAME: 9d2fc818>((-1 . <ENTITY NAME: 9d2fc818>) (0 . CIRCLE) (5 . 23A) (330 . <ENTITY NAME: 9d2f9590>) (100 . AcDbEntity) (67 . 0) (410 . Model) (8 . 0) (100 . AcDbCircle) (10 302.195 483.665 0.0) (40 . 27.7815) (210 0.0 0.0 1.0))7
    Polecenie: 

    i właśnie w tym momencie trochę zacząłem rozumieć o co chodzi z tym wszystkim.

    Modyfikując np. wartość w kodzie 40 w okręgu zmienimy jego średnice. Kod 10 odpowiada za współrzędne.

     

  10. Dziękuję teraz jest znacznie lepiej.

    (defun c:PETLA (/)
      (setq pnt1 (getpoint "Wskaz srodek polprostych: ")) 
      (initget (+ 1 2 4))
      (setq a (getint "\nPodaj ilosc polprostych: " ))
      (setq k (/ 360.0 a)) ; obliczam kat pomiedzy polprostymi
      (setq i 0) ; zmienna do petli
      (while i
      	(command "_line" pnt1 "D" 100 (* k i) "") ; rysowanie linii, kat pomnozony przez zmienna petli i
    	(setq i (1+ i)) ; zwiekszam o 1 wartosc zmiennej i
    	(if (= i a)  ; jesli mam dosc polprostych to wychodze z petli
    		(setq i nil)
    	)
    	
       )
    )

     

    Zastanawiam się jak zrobić żeby przy pytaniu o ilość program zaproponował coś domyślnie np. <23>:

    Trzeba taką zmienną zadeklarować wcześniej i potem jakoś wyświetlić w getint?

  11. No tak :)

    Mam takie coś:

    (defun c:PETLA (/)
      (setq pnt1 (getpoint "Wskaz srodek polprostych: ")) 
      (setq a (getint "\nPodaj ilosc polprostych: " ))
      (setq k (/ 360 a)) ; obliczam kat pomiedzy polprostymi
      (setq i 0) ; zmienna do petli
      (while i
      	(command "_line" pnt1 "D" 100 (* k i) "") ; rysowanie linii, kat pomnozony przez zmienna petli i
    	(setq i (1+ i)) ; zwiekszam o 1 wartosc zmiennej i
    	(if (= i a)  ; jesli mam dosc polprostych to wychodze z petli
    		(setq i nil)
    	)
    	
       )
    )

    Problem polega na tym, że jak kąt jest liczbą całkowitą np. 36 stopni to rysuje poprawnie. Jeśli to ułamek to nie rysuje wszystkich linii.

     

    2020-11-18 13_42_49-ZWCAD 2021 Wersja testowa (Pozostało 30 dni) - [Rysunek1.dwg].png

  12. Po próbach i poprawkach oraz uzupełnianiu nawiasów doszedłem do takiego skryptu:

    (defun c:WS (/)
      (setq pnt1 (getpoint "Wskaz srodek polprostych: "))
      (command "_line" pnt1 "D" 100 0 "")
      (command "_line" pnt1 "D" 100 30 "")
      (command "_line" pnt1 "D" 100 60 "")
      (command "_line" pnt1 "D" 100 90 "")
      (command "_line" pnt1 "D" 100 120 "")
      (command "_line" pnt1 "D" 100 150 "")
      (command "_line" pnt1 "D" 100 180 "")
    )

    ws.lsp

    Polecenie "WS". Skrypt pyta o wskazanie punktu i rysuje linie co 30 stopni.

    1369540586_2020-11-1712_56_09-ZWCAD2021Wersjatestowa(Pozostao30dni)-Rysunek1_dwg.png.aafa1d94fd19d1fbf879cb5c4811754d.png

     

    Teraz chyba czas na pętle.

     

  13. Zaciekawił mnie bardzo LISP. Niewiele wiem ale znalazłem starą książkę.

    Czytam powoli i w tym wątku chcę napisać co ciekawego udało mi się nauczyć :)

    Nawiasy i inne drobiazgi.

    • Wszystko ma być w nawiasach. 
    • Polecenia w cudzysłowach "".
    • Słowo "command" uruchamia polecenie programu.

    Przykład 

    (command "okrąg")


    powoduje uruchomienie rysowania okręgu.

    Za poleceniem możemy wpisać kolejne parametry np.

    (command "okrąg" "2.5,20" 30)

    Polecenie narysuje okrąg o środku w punkcie 2.5 i 20 o promieniu 30.

     

    Pauza czyli przystanek na żądanie.

    Słowo "pause" czeka na wskazanie czegoś przez użytkownika.

    To polecenie pozwala pokazać środek okręgu i rysuje okrąg o promieniu 5 i środku we wskazanym punkcie.

    (command "okrąg" pause 5)

    To rysuje prostokąt we wskazanym punkcie o szerokości 25, długość sami wprowadzamy.

    (command "prostokąt" pause "W" 25 pause)

     

  14. Potrzebowałbym taką funkcję do kopiowania (a może już jest?):

    1. wybieram funkcje i zaznaczam element
    2. teraz mogę wpisać odległość albo zmierzyć myszą
    3. dopiero teraz wskazuję punkt bazowy i kierunek
    4. po naciśnięciu enter program wykonuje kopię w wybranym kierunku
    5. po kolejnych naciśnięciach entera tworzone są kolejne kopie w takiej samej odległości od ostatniej kopi jak odległość w punkcie 2 i w tym samym kierunku - czyli jak w punkcie 2 wpisze odległość 60, to kopie będą w 60, 120, 180, 240, 300 itp.