kojacek

Użytkownik forum
  • Postów

    236
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    26

Treść opublikowana przez kojacek

  1. Zauważmy jednak że taki sam trójkąt możemy polilinią narysować na 2 sposoby: 1) Wskazując 3 punkty i zakończyć opcją zamknięcia. Wtedy ma 3 vertex-y i 3 segmenty 2) Wskazując 4 punkty (pierwszy i ostatni w tym samym punkcie) i dopiero zamknąć. Graficznie powstanie taki sam trójkąt, ale będzie miał 4 vertex-y, i 4 (ostatni zerowy) segmenty. Oba obiekty wyglądają tak samo, są jednak różne. Co do zadania domowego. Nie każdy czworobok jest prostokątem.
  2. Aby do końca doprowadzić sprawę poprawnego (do naszych celów) wyboru polilini, zauważmy jeszcze jeden przypadek. Oto bowiem wyobraźmy sobie polilinię zamkniętą składajacą się z dwóch segmentów łukowych. Niech to będzie księżyc (czy półksiężyc) na przykład. Do tej pory ograniczenia jakie nałożyliśmy to: polilinia zamknięta z trzema lub więcej segmentami. Musimy pochylić się nad ilością segmentów. Wychodzi na to że minimum trzy segmenty jest warunkiem koniecznym dla polilini składającej się segmentów prostoliniowych. Dla segmentów łukowych (choćby jeden łuk) bowiem, warunek spełniają już dwa segmenty. Jak tego dokonać w naszym Sel? Z pomocą przychodzi nam wiedza o budowie LWPOLYLINE, a w szczególności opis DXF wypukłości (bulge) czyli kody 42. Kody dotyczą opisu każdego wierzchołka, czyli w danych obietu występują wielokrotnie. Nie czas teraz opisywać szczegółowo co to jest bulge, teraz wystarczy nam wiedza że dla segmentów prostoliniowych kod 42 wynosi 0.0, dla łukowych zaś jest różny od 0.0. W istocie sprawdzenie czy dana polilinia składa się tylko z segmentów prostoliniowych, sprowadza się do sprawdzenia czy suma wszystkich kodów 42 jest równa zeru. Pamiętać należy także żeby bulge sprowadzić do liczb dodatnich (mogą być ujemne), tak aby nie zakłamać wyniku. Dla naszych celów przyda się także funkcja biblioteczna z CADPL-Pack'a, o nazwie cd:DXF_massoc, (całą bibliotekę można pobrać TU ) Funkcja zwraca listę wszystkich wartości zadanego kodu z listy DXF. I tak: jeśli d jest listą danych DXF obiektu, wywołanie: (cd:DXF_massoc 42 d) może zwrócić listę (np): (-0.517875 0.919164 0.0), teraz: (mapcar 'abs (cd:DXF_massoc 42 d)) zwraca: (0.517875 0.919164 0.0) a z: (apply '+ (mapcar 'abs (cd:DXF_massoc 42 d))) wynik będzie wynosił: 1.43704 Oczywiście dla polilini o zerowych bulge (segmenty prostoliniowe) - suma wszystkich zer, zwróci zero. I teraz mamy już naszą zmodyfikowaną funkcję Sel: (defun Sel (/ e d) (if (and (setq e (entsel "\nWskaż polilinię: ")) (= (cdr (assoc 0 (setq d (entget (car e))))) "LWPOLYLINE") (= 1 (logand 1 (cdr (assoc 70 d)))) (if (zerop (apply '+ (mapcar 'abs (cd:DXF_massoc 42 d)))) (>= (cdr (assoc 90 d)) 4) (>= (cdr (assoc 90 d)) 3) ) ) (princ "\nOk") (princ "\nŹle. ") ) ) Zadanie domowe: Napisać funkcję do wyboru polilinii będącej prostokątem... :)
  3. A teraz powinienem przybrać groźną minę i rzec, że oto podpuściłem was, a wy błędów nie widzicie... W rzeczywistości to sam go popełniłem. Chodzi o formę: (>= 4 (cdr (assoc 90 d))) bowiem powinno być: (>= (cdr (assoc 90 d)) 4) ponieważ porównanie "większe / równe niż" odnosi się do "prawej" strony, czyli do drugiego argumentu. W naszym przypadku ilość wierzchołków ma być równa lub większa niż 4, a nie odwrotnie. Prawda?
  4. Od końca. Ilość wierzchołków to jedyna wartość dla kodu 90. Stąd od razu porównanie. Dla zamknięcia sprawa jest bardziej złożona. Kod 70 zawiera jednocześnie informację czy polilinia jest zamknięta, oraz czy generowanie rodzaju linii jest włączone czy nie. I tak: 0 - poly otwarta a 1 zamknięta. PLINEGEN zaś to wartość 128. Stąd test zamknięcia polilinii sprowadza się do sprawdzenia logand = 1 (1 i 129 to zamknięta).
  5. Jeśli można tutaj (chyba że admin przeniesie do innego wątku), od samego początku. Czyli wybór obiektu. Niech będzie prosta funkcja o nazwie Sel do wyboru jednego obiektu. Do testowania zwracać będzie wynik Ok lub Źle. W kolejnych krokach trochę urośnie, ale pozwoli to prześledzić działanie. Podobnie jak w twoim kodzie, chcemy wybrać obiekt (polilinię). Spójrz: (defun Sel (/ e) (if (setq e (entsel "\nWskaż polilinię: ")) (princ "\nOk") (princ "\nŹle. ") ) )   Powiedzmy szczerze że żadnych rewelacji, nie trafisz - masz źle, wybierzesz jest Ok. Powiela twój błąd - możesz wybrać cokolwiek, a chcesz przecież polilinię. Zatem druga przymiarka: (defun Sel (/ e d) (if (and (setq e (entsel "\nWskaż polilinię: ")) (= (cdr (assoc 0 (setq d (entget (car e))))) "LWPOLYLINE") ) (princ "\nOk") (princ "\nŹle. ") ) ) W and od razu pobieramy dane obiektu (zmienna d), jednocześnie sprawdzamy czy to polilinia. Lepiej? Lepiej ale... w twoim przypadku trzeba wybrać polilinię zamkniętą raczej. Zatem popatrzmy: (defun Sel (/ e d) (if (and (setq e (entsel "\nWskaż polilinię: ")) (= (cdr (assoc 0 (setq d (entget (car e))))) "LWPOLYLINE") (= 1 (logand 1 (cdr (assoc 70 d)))) ) (princ "\nOk") (princ "\nŹle. ") ) ) and ma teraz trzy warunki ( 1.wybraliśmy obiekt, 2.polilinię i 3.zamkniętą). Zamknięta polilinia w DXF to kod 70. Musi mieć wartość 1 (oraz ewentualnie 129). Jest dużo lepiej. Ale to nie koniec. Właściwie, to powinieneś wybrać zamkniętą polilinię ale o co najmniej 3 segmentach... Więc zmieniamy sel: (defun Sel (/ e d) (if (and (setq e (entsel "\nWskaż polilinię: ")) (= (cdr (assoc 0 (setq d (entget (car e))))) "LWPOLYLINE") (= 1 (logand 1 (cdr (assoc 70 d)))) (>= 4 (cdr (assoc 90 d))) ) (princ "\nOk") (princ "\nŹle. ") ) ) I teraz mamy już bardziej (niż mniej) poprawny kawałek kodu do wybrania polilini...
  6. Nie wydaje mi się aby zabawy z obracaniem obiektów, będą efektywniejsze niźli LISP który wskazałem we wcześniejszym poście. Wykorzystuje on algorytm Grahama (wyznaczenie otoczenia punktów), sprowadzając wynik ostatecznie w uproszczeniu do najmniejszego prostokąta (o co w rzeczywistości chodzi). Wydaje mi się że działa dobrze w większości zastosowań.
  7. Co do znalezienia najmniejszego prostokąta (opisującego płaską figurę) zobacz tutaj: http://www.theswamp.org/index.php?topic=33607.msg389707#msg389707 Jest tam program do ściągnięcia: http://www.theswamp.org/index.php?action=dlattach;topic=33607.0;attach=15988 Potestuj i zobacz czy spełnia twoje oczekiwania. Co do lisp-ów zaś, zobacz tutaj: http://forum.cad.pl/cadpl-pack-v1-lsp-t78161.html To o takim zjawisku o nazwie CADPL-Pack. Jest to zestaw funkcji bibliotecznych, których użycie (także w twoim omawianym tutaj problemie), znacznie może ułatwić pracę. Również sama dyskusja przy poczęciu i rozwoju Pack-a, (w mojej opinii) może być źródłem porządnej lisp-owej wiedzy. W tej chwili widzę już na początku wiele błędów w twoim kodzie. Chętnie (w miarę możliwości czasowych) służę pomocą, w ich ewentualnej poprawie i wyjaśnieniu na czym polegają.
  8. Nie mieć jak u "starszego brata" wyboru tegoż?
  9. kojacek

    Rebus piątkowy

    Ok, to szybciej. 1) Rysuję wymiar kąta małego 2) Wybieram wymiar (z uchwytu wymiaru) szeregowy, wskazuję punkt 3) wymazuję wymiar z 1) (mały) :)
  10. kojacek

    Rebus piątkowy

    W AutoCAD-zie zrobiłem to (przed chwilą) tak: 1. Narysowałem łuk (na zewnątrz linii) 2. Poleceniem _DIMARC (WYMŁUK) go zwymiarowałem 3. Usunąłem łuk 4. Ręcznie edytowałem wartość, usunąłem znak długości łuku Może być?
  11. kojacek

    Rebus piątkowy

    Można to zrobić np. LISP-em: (sqrt 49) zwraca 7.0... Symbolem zatem będzie pierwiastek (?)
  12. Bez urazy, ale test ów przypomina radzieckie badania dotyczące stopniowej utraty słuchu muchy w zależności od ilości nóg... Po wyrwaniu ostatniej nogi i komendzie "Idi-mucha!" akademicy radzieccy udowodnili całkowity brak reakcji na bodźce dźwiękowe... ;)
  13. To jest raczej wada, w moim przekonaniu. AutoCAD podstawia czcionkę zastępczą zawsze. Oczywiście można określić swoje preferencje, ale nawet gdy to się zignoruje, wstawiany jest standard.
  14. O to, to... właśnie. Brakuje pliku shx tylko dla symboli, dla czterech pozostałych stylów to: (3x) isocp.shx (+ bigfont.shx) oraz (1x) txt.shx
  15. W AutoCAD widać wszystko ok. Na początku jest komunikat o braku czcionki, chodzi o symbole. Na zrzucie pokazuję jakiej czcionki i dla jakiego stylu:
  16. To raczej niemożliwe. Tekstów brak wszędzie, w opisach, atrybutach, wymiarach. Ponadto, takie działanie nie miałoby żadnego uzasadnienia. AutoCAD ma mechanizm podstawiania czcionek zastępczych (z określeniem co może być zastąpione). Nie ma sytuacji, aby tekst się nie pojawił - gdy nie ma żadnej odpowiedniej czcionki, AutoCAD, podstawia standardową dla wszystkich tekstów. Styl tekstu STANDARD, jest nieusuwalny.
  17. Nie wiem czy dobrze czytam i patrzę, ale odnoszę wrażenie że w AutoCAD widać wszystko dobrze?
  18. Sprawdź teraz: ;;; (vl-load-com) ;;; (defun C:CDIST (/ sa sb vo re) (if (setq sa (nentselp "\nWskaz pierwszy punkt na krzywej: ")) (if (setq sb (nentselp "\nWskaz drugi punkt na krzywej: ")) (if (and (eq (car sa)(car sb))) (progn (setq vo (vlax-ename->vla-object (car sa))) (setq re (abs (- (vlax-curve-getDistAtPoint vo (vlax-curve-getClosestPointTo vo (cadr sa) t) ) (vlax-curve-getDistAtPoint vo (vlax-curve-getClosestPointTo vo (cadr sb) t) ) ) ) ) ) (princ "\nWskazano rózne obiekty. ") ) (princ "\nNic nie wskazano. ") ) (princ "\nNic nie wskazano. ") ) (if re re (princ)) )
  19. Zawsze można użyć LISP-a: Poniższy kod pozwoli zmierzyć długość elementu dowolnej krzywej pomiędzy dwoma punktami na niej wskazanymi: ;;; (vl-load-com) ;;; (defun C:CDIST (/ sa sb vo) (if (setq sa (nentselp "\nWskaz pierwszy punkt na krzywej: ")) (if (setq sb (nentselp "\nWskaz drugi punkt na krzywej: ")) (if (and (eq (car sa)(car sb))) (progn (setq vo (vlax-ename->vla-object (car sa))) (abs (- (vlax-curve-getDistAtPoint vo (vlax-curve-getClosestPointTo vo (cadr sa) t) ) (vlax-curve-getDistAtPoint vo (vlax-curve-getClosestPointTo vo (cadr sb) t) ) ) ) ) (princ "\nWskazano rózne obiekty. ") ) (princ "\nNic nie wskazano. ") ) (princ "\nNic nie wskazano. ") ) (princ) ) .
  20. Bezpośrednio nie ma. Choć można wysmażyć krótkiego lisp-a. Inna sprawa - w węzłach polilini nie będzie raczej "prostopadłych".
  21. Nie tam żebym upierał się aby odwodzić was od komplikowania sobie pracy, ale... może warto wykorzystać opcję _block do podziału?
  22. Swego czasu (miljon lat temu...) w AutoCAD-zie, robiłem coś takiego: http://kojacek.republika.pl/bkg.html
  23. To jeszcze prostsze ;) Język ów nazywa się: AutoLISP
  24. To proste, z wymienionej wyżej linii usuń sekwencję znaków "_x" Wtedy wywołanie: (if (setq % (ssget '((0 . "LINE")(62 . 5)(410 . "Model"))))(sslength %) 0) poprosi Cię o wskazanie obiektów
  25. Nie tam żebym się wtrącał czy coś,... ale wystarczy w linii poleceń wpisać: (if (setq % (ssget "_x" '((0 . "LINE")(62 . 5)(410 . "Model"))))(sslength %) 0) i zaakceptować enterem... Takie proste (bezbajtowe wręcz) wklepanie z klawiaturki, ma tę przewagę nad skompilowanymi plikami *.zel (nic im nie ujmując), że można zawsze zmienić dowolnie albo rodzaj obiektu czy kolor, bez tworzenia nowego pliku, definicji polecenia i podpinania ikonek. Może to i mniej spektakularne rozwiązanie, ale w mojej opinii bardziej elastyczne... Jutro kolega będzie chciał wybrać czerwone łuki... i co będzie?