AutoCAD... AutoLISP... VisualLISP...

  [55] Wieloboki podobne

index  

  Wyszukiwanie w rysunku figur podobnych. Taki z pozoru prosty temat pojawił się jakiś czas temu na www.cad.pl. Piszę z pozoru - bo w rzeczywistości (w AutoCAD-zie) wymaga to nieco zachodu. Dla ułatwienia zajmiemy się wielobokami foremnymi. Do utworzenia w AutoCAD-zie wieloboku (foremnego) służy polecenie WIELOBOK (_POLYGON). Rysowane wieloboki nie są osobnymi specjalnymi obiektami - są po prostu poliliniami zamkniętymi. Stąd też wybór takich obiektów jako figur podobnych, sprowadza się do porównania pewnych cech polilinii (zwykle ilości wierzchołków i odległości pomiędzy nimi - co właściwie wystarcza, do określenia podobieństwa).
Ponieważ (w kontekście AutoCAD-a), mówimy o obiektach typu polilinia, definicja musi być przystosowana do tego typu obiektów, zatem warunki dla dowolnego wieloboku foremnego są następujące:
  • obiekt musi być polilinią
  • polilinia musi być zamknięta
  • polilinia musi posiadać określoną (>= 3) liczbę wierzchołków
  • polilinia nie może mieć innych bulge (wypukłości) niż =0, co oznacza że segmenty (boki) są liniowe
Poniższe rysunki ilustrują sytuację dla różnych polilinii, które mają 3 wierzchołki, a odległości pomiędzy nimi są równe. Wykazują one jasno że należy sprawdzać zawsze wszystkie powyższe warunki.
PRZYKŁAD 1: Obiekt jest polilinią. Polilinia ma 3 wierzchołki, odlogłości między nimi są równe, segmenty są liniowe. Niespełniony warunek - polilinia nie jest zamknięta.
PRZYKŁAD 2: Obiekt jest polilinią. Polilinia ma 3 wierzchołki, jest zamknięta, odległości między wierzchołkami są równe. Niespełniony warunek - polilinia posiada bulge inne niż 0.
PRZYKŁAD 3: Obiekt jest polilinią. Polilinia ma 3 wierzchołki, jest zamknięta, odległości między wierzchołkami są równe. Taki obiekt jest trójkątem równobocznym.
Sprawdzenie warunków wykonujemy oczywiście LISP-em. Ponieważ część warunków dla wszystkich sytuacji jest taka sama (polilinia, segmenty liniowe, zamknięcie) - definiujemy funkcję sprawdzającą właśnie te podstawowe warunki:
;; ----------------------------------------------------------------------------- ;
;; Funkcja sprawdza czy dane DXF (d) są danymi polilinii zamknietej, o (v) wie-  ;
;; rzchołkach, i wszystkich segmentach liniowych.                                ;
(defun jk:GEO_Poly-Closed-N-Vert (d v / b)
  (if
    (= (cdr (assoc 0 d)) "LWPOLYLINE")
    (progn
      (setq b (jk:DXF_massoc 42 d))
      (if
        (and
          (zerop (eval (append '(min) b)))
          (zerop (eval (append '(max) b)))
        )
        (if
          (= v (cdr (assoc 90 d)))
          T
          nil
        )
        nil
      )
    )
    nil
  )
)

Teraz dopiero możemy sprawdzić (po spełnieniu wcześniejszych warunków) czy polilinia ma 3 wierzchołki, i czy odległości między nimi są równe. W tym celu definiujemy specjalną funkcję (wykorzystującą wcześniej zdefiniowaną). Funkcja wygląda tak:
;; ----------------------------------------------------------------------------- ;
;; Funkcja sprawdza czy polilinia (e) jest trójkątem równobocznym. Zwraca T/nil  ;
(defun jk:GEO_Poly-EqLnTriangle (e / d p d1 d2 d3 f)
  (setq d (entget e))
  (if
    (jk:GEO_Poly-Closed-N-Vert d 3)
    (progn
      (setq p (jk:DXF_massoc 10 d)
            d1 (distance (car p)(cadr p))
            d2 (distance (cadr p)(caddr p))
            d3 (distance (car p)(caddr p))
            f 0.0000001
      )
      (if
        (and
          (equal d1 d2 f)
          (equal d2 d3 f)
          (equal d3 d1 f)
        )
        T
        Nil
      )
    )
    nil
  )
)
Funkcje wymagają innej funkcji bibliotecznej jk:DXF_massoc, którą można odszukać tu: [20] Obwiednia regionu. Prezentowane powyżej rozwiązania można zastosować do budowy innych funkcji sprawdzających właściwości obiektów (polilinii), będących wielobokami foremnymi.
Na zakończenie. Funkcja sprawdzająca czy polilinia jest (ogólnie) prostokątem. Sprawdzane warunki: 4 wierzchołki i równe przekątne. Funkcja wygląda tak:
;; ----------------------------------------------------------------------------- ;
;; Funkcja sprawdza czy polilinia (e) jest prostokatem. Zwraca T lub nil         ;
(defun jk:GEO_Poly-Rectang (e / d p d1 d2 f)
  (setq d (entget e))
  (if
    (jk:GEO_Poly-Closed-N-Vert d 4)
    (progn
      (setq p (jk:DXF_massoc 10 d)
            d1 (distance (car p)(caddr p))
            d2 (distance (cadr p)(cadddr p))
            f 0.0000001
      )
      (if (equal d1 d2 f) T nil)
    )
  )
)
Wszystkie funkcje LISP-a, będą działały na wszystkich wersjach AutoCAD-a począwszy od Release 14 (wprowadzony obiekt LWPOLYLINE).
  aktualizacja: 21-12-2009