Iskra

Użytkownik forum
  • Postów

    6
  • Dołączył

  • Ostatnia wizyta

Osiągnięcia Iskra

Początkujący

Początkujący (1/6)

0

Reputacja

  1. W końcu udało mi się przysiąć i trochę nadrobić zaległości. Ostatni dni mi wypadły ze wzgledu na 2 dniowe szkolenie. Kod kojacka działa bez zarzutu. Mała tylko uwaga a właściwie pytanie dotyczy czy zawsze przed nazwą funkcji trzeba wpisywać c:. Bez tego nie mogłem uruchomić funkcji. Teraz jest (defun SelRect (/ e d rect-p) zamiast: (defun c:SelRect (/ e d rect-p) Po za tym wszystko działało. Ja przynajmniejnie znalazłem żadnych wyjątków. Co do kodu kruszyńskiego nie udało mi się go odpalić. Szukałem błedów ale bezskutecznie. Autocad wskazuje zbyt małą ilość argumentów. Wczytano pomyślnie test1.LSP. Polecenie: ; błąd: zbyt mało argumentów: (IF (AND (NOT (ZEROP (DISTANCE (CAR P) (CADDDR P)))) (EQUAL (DISTANCE (CAR P) (CADDR P)) (DISTANCE (CADR P) (CADDDR P)) 0.001))) Co do metody wydaje mi się że samo sprawdzenie lepiej byłoby zrobić w jednym bloku i uzyskać odpowiedź. Przy każdej linijce wpisując komentarz co sprawdzamy. Ewentualnie wypisać w linii definiowania funkcji wpisać komentarz z poszczególnymi warunkami w kolejności w jakiej póżniej występują. Analizując kod kryszyńskiego trochę mnie zmyliło sprawdzenie warunku ilości wierzchołków. (defun IsPolyline ( / ) (= (cdr (assoc 0 EntityList)) "LWPOLYLINE") ) (defun IsClosed ( / ) (= 1 (logand 1 (cdr (assoc 70 EntityList)))) ) (defun NumberOfVertex ( / ) (cdr (assoc 90 EntityList)) ) (defun HasArcSegment (EntityList / ) (zerop (apply '+ (mapcar 'abs (cd:DXF_massoc 42 EntityList)))) ) IsPolyline oraz IsClose jest wykonywana w całości i zwraca T lub nil NumberOfVertex zwraca ilość wierzchołków o dopiero pod koniec sprawdza czy ilośc się zgadza. Jeżeli od początku nastawiamy się na sprawdzenie czemu od razu nie wpisać całego warunku. (defun NumberOfVertex ( / ) (= 4 (cdr (assoc 90 EntityList))) Z drugiej strony nazywanie funkcji tak jak zrobił to kruszyński bardzo mi się spodobało. Podczas pisania zajmuje wiecej czasu ale samo czytanie później kodu jest dużo łatwiejsze. Nie wymaga rozpisywania wszystkich wprowadzonych zmiennych lub funkcji. Przy większych programach lub w przypadku gdy funkcja będzie wykorzystywana kilkukrotnie jest to duze udogodnienie przy programowaniu. Mam też coś co mi siedzi w głowie od paru dni i nie mogę znaleźć rozwiązania. Jak sprawdzić kierunek dla polilinii zamkniętej. Chodzi mi o to aby dowolny wielobok z polilinii był rysowany w kierunku przeciwny do kierunku wskazówek zegara. Nie jest to potrzebne do programu "najmniejszy opisany prostokąt" ale skoro już wałkujemy tą polilinię, pomyślałem, że dorzucę tutaj powyższe zagadnie. Maszyna CNC na której pracuje musi mieć podany zawsze keriunek jak wyżej. Chodzi o to że maszyna frezuje zawsze po prawej stronie od wskazanej ścieżki. Jezeli kierunek jest odwrócony wytnie zły element. w Autocadzie nie widać jaki jaki kierunek ma polilinia, dopiero jak podczytam dxf to wyskakują mi błędy. Pierwsza myśl była aby znaleźć środek ciężkości figury i sprawdzić kąty między odcinkami. Jeżeli byłyby dodatnie (rosnące) to wtedy uznać że figura jest prawidłowa. Problem jest jeżeli figura miałaby wklęśnięcia i środek ciężkości by wypadł poza obrys figury. Wtedy zczytywane kąty byłyby ujemne mimo prawidłowego kierunku.
  2. Z mojej strony dodam ze program powinien rozpoznawac prawidlowa polilinie od 3 wezlow (tzn od trojkatow), jezeli nie ma zadnych lukow. Przy poliliniach z lukami od 2 wezlow przy sprawdzeniu warunkow sumy "bulge " rozna od 0. Pytanie tylko czy nasz program chcemy ograniczyc do polilinii zamknietych czy moze powinien analizowac wszystkie mozliwosci. Jezeli celem jest stworzenie funkcji opisujacej prostokat na wskazanej polilinii to powinna ona tez uwzgledniac te niedomkniete. Nie mam na tyle doswiadczenia aby przewidziec jak bedzie to wygladalo na pozniejszym etapie tzn. czy mozna napisac program uniwersalny dla wszystkich przypadkow czy dla kazdego sortu bedzie potrzebny inny program. Co do pracy domowej to nie mam kiedy przysiasc i napisac kod ale pomysl jest taki zeby sprawdzic nastepujace warunki: 1) ilosc wierzcholkow =4 (90 . 4) 2) polilinia zamnkieta (70 . 1) 3) przekatne sa sobie rowne (= d1 d2), wciagnac wspolrzedne punktow i policzyc (setq d1 (distance pt1 pt3)) (setq d2 (distance pt2 pt4)). Dla prostokatow z 5 segmentow (ostatni segment zerowy) konieczna byloby sprawdzenie czy pierwszy punkt jest rowny ostatniemu.
  3. potrzebna byla krotka powtorka z liczb binarnych ale teraz jest juz wszystko jasne. Dzieki
  4. ok, 99% kodu jest dla mnie jak najbardziej zrozumiala. Tylko czemu w 3-ciej wersji dodajesz iloczyn logiczny (logand) przy sprawdzeniu zamkniecia polilinii? Ma to jakies uzasadnienie? W 4-rtej wersji przy sprawdzeniu ilosci wierzcholkow, porownujesz bezposrednio liczby po wyciagnieciu 2-go elementu.
  5. Wowww :shok: ... jak zaczynalem zabawe LISP-em to widzialem tylko pare stron funkcji i stwierdzilem ze idzie to ogranac. Bazowalem glownie na zestawieniu funkcji z e-cad.pl i ksiazki AutoLISP - Praktyczny Kurs. A tu im dalej w las tym wiecej drzew...ilosc mozliwosci mocno mnie zaskoczyla. Wielke dziekie Kojacek, program ze SWAP-a sprawdza sie w 100%, dokladnosc jest jak najbardziej wystarczajaca. CADPL-Pack tez robi wrazenie, ale narazie jeszcze sie w niego nie wgryzalem. Mam zajecie na kilka tygodni ale chetnie bym tez uslyszal Twoje uwagi odnosnie mojego kodu. Oczywiscie jak bedziesz mial chwile. Sam bym teraz sporo rzeczy zmienil. Przede wszystkim zaczal uzywac podprogramow. Teraz robilem wszystko w jednym ciagu i jak mi przyszlo cos zmienic to szukanie zabieralo zbyt duzo czasu. Co do funkcji GetBoundingBox moze zastapic moje wyliczenia min i max oraz okresla prawidlowo te punkty rowniez dla lukow. Jednak nie sprawdza sie juz w przypadku splajnu. Wyrzuca punkty polozone troche dalej niz wskazany splajn. Te cos nowego na co nie zwrocilem wczesniej uwagi, do momentu uzycia programu ze SWAP-a. Pozostaje zakasac rekawy i do roboty. Wielkie dzieki za pomoc :good: A tak na marginesie istnieje cos takiego jak spis wszystkich podstawowych funkcji VLispa? Cos takiego jak jest na stronie e-cad.pl dla Autolispa. ps. Przepraszam za brak polskich znakow ale w pracy nie posiadam "polskiej klawiatury"
  6. Witam wszystkich, Na początku krótko o mnie. Z LISP-em mam doczynienia dopiero od 2 msc. Nigdy wczesniej też nie pisałem postów na formu więc jeśli robię coś źle dajcie znać. Przy pracy na pełny etat i dwójce małych dzieci nie ma za wiele czasu, ale staram się jak mogę i oto poniżej jest mój pierwszy "użytkowy program". :) Mam mały, mianowicie nie zawsze działa poprawnie. Program powinien rysować na wskazanej polilinii opisany prostokąt o najmniejszej powierzchni. Służy mi to w pracy do wyliczania powierzchni fasady wentylowanej. Do oferty trzeba ująć właśnie najmniejszy opisany prostokąt, jeżeli płyta ma nieforemny kształt. Jak na załączonym zdjęciu, czasami omija jeden punkt. Niebieskie to analizowana polilinia natomiast żółte to efekt działania programu. Program znajduje się natomiast tutaj: (setq PL (entsel "\nWSKAŻ POLILINIĘ : ")) (if (= PL nil) (progn (alert "Musisz wskazac POLILINIĘ") (vl-exit-with-value 0) );progn );if (setq PL (car PL)); wyciąga nazwe ze wskazanej polilinii (setq vla_PL (vlax-ename->vla-object PL); zamienia nazwe obiektu z typowej numeracji ACAD na nazwy obiektowe ILOSC_WIERZCHOLKOW (vlax-curve-getEndParam vla_PL)); zlicza ilosc wierzchołków wskazanej polilinij (setq i 0) (setq Petla (fix ILOSC_WIERZCHOLKOW)) ;fix: Real -> Integer (setq Dane_i (list)) ;**************************************************************** ;UTORZENIE MACIERZY PUNKTOW Z KTORYCH ZBUDOWANA JEST POLILINIA (PKT1 X Y Z ...) (repeat (+ Petla 1) ; wyciagamy punkt z PL (Polilinii) (setq Punkt_1 (vlax-curve-getpointAtParam vla_PL i)) (setq P1_x (car Punkt_1) P1_y (cadr Punkt_1) P1_z (caddr Punkt_1) Dane_i (cons i Dane_i) Dane_i (cons P1_x Dane_i) Dane_i (cons P1_y Dane_i) Dane_i (cons P1_z Dane_i) );setq (setq i (1+ i)) );repeat (setq Dane_i (reverse Dane_i)) ; Dane_i - ciągła lista wszystkich wierzchołków (nr i X, Y, Z wierzcholka) ;*************************************************************** ;WPROWADZENIE POCZATKOWEGO POLA POWIERZCHNI PROSTOKATA OPISANEGO (setq k 2 Xmin (nth 1 Dane_i) Xmax (nth 1 Dane_i) Ymin (nth 2 Dane_i) Ymax (nth 2 Dane_i) );setq (while (<= k Petla) (progn (setq X (nth (- (* k 4) 3) Dane_i) Y (nth (- (* k 4) 2) Dane_i) );setq (if (< X Xmin) (setq Xmin X) );if (if (> X Xmax) (setq Xmax X) );if (if (< Y Ymin) (setq Ymin Y) );if (if (> Y Ymax) (setq Ymax Y) );if (setq k (1+ k));setq );progn );while ;*********************************************************** ;Wyznaczenie prostokata na podstawie min i max punktow X i Y (setq Pkt1 (list Xmin Ymin) Pkt2 (list Xmax Ymin) Pkt3 (list Xmax Ymax) Pkt4 (list Xmin Ymax) L (distance Pkt1 Pkt2) H (distance Pkt2 Pkt3) Pole (* L H); Pole koncowe Pmin Pkt1; Punkt 1 koncowy Pmax Pkt3; punkt 2 koncowy kat 0; kat koncowy );setq ;(princ "\nPoczatkowa powierzchnia prostokata wynosi: ") ;(princ Pole) ;(princ " o wymiarach LxH = ") ;(princ L) (princ " x ") (princ H) ;(princ "\noraz punktach wstawienia P1: ") (princ Pmin) (princ " oraz P2: ") (princ Pmax) ;*************************************************************** (setq i 1 j (+ i 1) );setq (while (< i Petla) (progn (while (<= j Petla) (progn (setq P1 (list (nth (- (* i 4) 3) Dane_i) (nth (- (* i 4) 2) Dane_i) (nth (- (* i 4) 1) Dane_i)) P2 (list (nth (- (* j 4) 3) Dane_i) (nth (- (* j 4) 2) Dane_i) (nth (- (* j 4) 1) Dane_i)) kat_rad (angle P1 P2) kat_grad (angtos kat_rad 0 10) );setq ;**************************************************************** (command "_ucs" "_z" P1 P2) ;WYSZUKANIE SKRAJNYCH PUNKTOW W AKTUALNYM UKLADZIE WSPOLRZEDNYCH (setq k 2 X_ (nth 1 Dane_i) Y_ (nth 2 Dane_i) Z_ (nth 3 Dane_i) Punkt (list X_ Y_ Z_) Punkt (trans Punkt 0 1 nil) Xmin (nth 0 Punkt) Xmax (nth 0 Punkt) Ymin (nth 1 Punkt) Ymax (nth 1 Punkt) );setq (while (<= k Petla) (progn (setq X (nth (- (* k 4) 3) Dane_i) Y (nth (- (* k 4) 2) Dane_i) Z (nth (- (* k 4) 1) Dane_i) Punkt (list X Y Z) Punkt (trans Punkt 0 1 nil) X (nth 0 Punkt) Y (nth 1 Punkt) );setq (if (< X Xmin) (setq Xmin X) );if (if (> X Xmax) (setq Xmax X) );if (if (< Y Ymin) (setq Ymin Y) );if (if (> Y Ymax) (setq Ymax Y) );if (setq k (1+ k));setq );progn );while ;Wyznaczenie opisanego prostokata na skrajnych punktach (setq Pkt1 (list Xmin Ymin) Pkt2 (list Xmax Ymin) Pkt3 (list Xmax Ymax) Pkt4 (list Xmin Ymax) L (distance Pkt1 Pkt2) H (distance Pkt2 Pkt3) P_ucs (* L H); Pole w aktualnym ukladzie );setq (if (< P_ucs Pole) (setq Pole P_ucs Pmin Pkt1; Punkt 1 koncowy Pmax Pkt3; punkt 2 koncowy Pmin (trans Pmin 1 0 nil) Pmax (trans Pmax 1 0 nil) kat kat_grad );setq );if ;(command "_rectangle" Pkt1 "_r" kat Pkt3) (command "_ucs" "_w") ;*************************************************************** (princ "\nWspółrzedne odcinka ") (princ i) (princ " - ") (princ j) (princ " wynoszą: ") (princ P1) (princ " oraz ") (princ P2) (setq j (1+ j));setq );progn );while j (setq i (1+ i) j (+ i 1));setq );progn );while i (princ) (command "_rectangle" Pmin "_r" kat Pmax) Ogólne założenie programu jest takie, że zczytuje on punkty polilinii a następnie łączy je w pary np. dla czworokąta są następujące 1-2, 1-3, 1-4, 2-3, 2-4, 3-4. Dla każedej pary zmianie układ współrzędnych tak aby oś X leżała na wskazanym odcinku. Po zmianie układu odczytuje wartości X i Y wszystkich punktów i wyszukuję najmniejsze i największe wartości. Nie umiałem tutaj zastosować funkcji "min" i "max" dlatego zrobiłem to za pomocą funkcji "if" i w przydaku prawdy zmiania główną wartość Xmin, Xmax, Ymin albo Ymax. Po wyszukaniu punktów odczytuje wartość długość i wysokość i wylicza powierzchnie. Wybór najmniejszego prostokąta również za pomocą funkcji "if" jeżeli prawda to zastępuję główną wartość i zapamiętuje prarametry prostokąta tzn. dł, wys, kąt obrotu oraz pow. Będę wdzięczny za wskazówki. Problem drugi którym się jeszcze nie zajmowałem to podobny program ale dla polilinii posiadających łuk. Moj program widzi naturalnie tylko konce łuk. Czy jest możliwe wyszukanie punktu min lub max dla wskazanej polilinii? Np. na zasadzie przesuwania linii o wskazany wektor i jeżeli są 2 punkty przecięcia to zwiększa wektor jeżeli 0 to różnicę między wektorami dzieli na pół i tak do skutku aż znajdzie tylko 1 wspólny punkt. To taki mój pomysł ale jeszcze nie prubowałem go zrealizować. Narazie chciałbym usprawnić program dla wielokątów. Będę wdzięczny za wszelkie wskazówki co może być nie tak. Pozdrawiam