Prostokąt obejmujący MTEXT i transformacje układów współrzędnych


Rekomendowane odpowiedzi

Witam.

W kontekście Prostokąt obejmujący Podjąłem próbę uzupełnienia o obsługę obiektu MTEXT tak aby obrys obejmował tekst rzeczywisty a nie obszar na niego zarezerwowany. Z tego względu funkcja vla-GetBoundingBox się nie sprawdzi. Popełniłem kawałek kodu do rysowania ramki i przy o tej okazji napotkałem szereg problemów związanych z wyznaczaniem obszaru, justowaniem, dopasowaniem do punktu wstawienia etc. Poniższy kod wykorzystuje do tworzenia obiektów w przestrzeni 3D command'y. Działa, ale nie wygląda zbyt dobrze. Pierwsza sprawa jak przerobić to na kod operujący na danych obiektu MTEXT bez korzystania z command czyli wyłuskując dane obiektu i transformując współrzędne. Tu pojawia się problem i moje pytanie. Jak dokonać transformacji układu ECS na WCS i odwrotnie aby po obliczeniach analitycznych wrysować obrys w płaszczyźnie obiektu MTEXT. Przy okazji w kodzie umieściłem próbę wrysowania obrysu za pomocą  vla-GetBoundingBox ale obiekt ten dostaje dziwnej elewacji i nie jest umieszczany w płaszczyźnie tekstu ale za to do niego równoległej. Natomiast linia kontrolna (przekątna) nie trzyma się płaszczyzny tekstu. Podobny efekt występuje w funkcji Obrys przywołanego na wstępie kudu, który działa prawidłowo tylko dla WCS'a. Potrzebowałbym pomocy w rozwikłaniu tego problemu. W załączeniu lisp i dwg demo.

 image.png.6bb75abc270f797a8bbcb1c462a21675.png

(vl-load-com)

(defun c:MTextBorder ( / ent entName systemEnv IPT APT WDT HGT NV LB RT)

    ; (defun local:AddPLine ( points / mSpace pointArray pLineObj )
    ;     (setq 
    ;         mSpace (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
    ;         pointArray (vlax-make-safearray vlax-vbDouble '(0 . 2))
    ;     )
    ;     (vlax-safearray-fill pointArray points)
    ;     (vla-AddPolyline mSpace pointArray)
    ; )

    ; (defun local:DrawBox (p1 p2 bwl bwr bwb bwt)
    ;     (list 
    ;         (list (- (car p1) bwl) (- (cadr p1) bwb) 0)
    ;         (list (- (car p1) bwl) (+ (cadr p2) bwt) 0)
    ;         (list (+ (car p2) bwr) (+ (cadr p2) bwt) 0)
    ;         (list (+ (car p2) bwr) (- (cadr p1) bwb) 0) 
    ;     )
    ; )

    (defun local:XLB (APT WDT)
        (cond
            ((= (rem APT 3) 1) 0)
            ((= (rem APT 3) 2) (* -1 (/ WDT 2)))
            (T (* -1 WDT))
        )
    )

    (defun local:XRT (APT WDT)
        (cond
            ((= (rem APT 3) 1) WDT)
            ((= (rem APT 3) 2) (/ WDT 2))
            (T 0)
        )
    )

    (defun local:YLB (APT HGT)
        (cond
            ((or (= APT 1) (= APT 2) (= APT 3)) (* -1 HGT))
            ((or (= APT 3) (= APT 4) (= APT 5)) (* -1 (/ HGT 2)))
            (T 0)
        )
    )

    (defun local:YRT (APT HGT)
        (cond
            ((or (= APT 1) (= APT 2) (= APT 3)) 0)
            ((or (= APT 3) (= APT 4) (= APT 5)) (/ HGT 2))
            (T HGT)
        )
    )

    (if (setq ent (entsel))
        (progn
            (setq
                ; systemEnv (cd:ENV_SaveEnvVariable)
                entName (entget (car ent))
			    IPT (cdr (assoc 10 entName)) ; insert point
			    APT (cdr (assoc 71 entName)) ; attachment point
			    WDT (cdr (assoc 42 entName)) ; width
			    HGT (cdr (assoc 43 entName)) ; height
                ANG (cdr (assoc 50 entName)) ; angle
                NV (cdr (assoc 210 entName)) ; normal vector
                LB (list (local:XLB APT WDT) (local:YLB APT HGT) 0) ; left bottom point
                RT (list (local:XRT APT WDT) (local:YRT APT HGT) 0) ; right top point
            )

            ; save current UCS
            (setvar "osmode" 0)
            (setvar "cmdecho" 0)
            (command "_ucs" "_d" "tmp" "")
            (command "_ucs" "_s" "tmp")

            ; use native commands
            (command "_ucs" "_ob" ent)
            (command "_ucs" "_o" (trans IPT 0 1))
            (command "_rectang" LB RT) 

            ; using ActiveX to determine the coordinates of corners and transform coordinate systems
            (vla-GetBoundingBox (vlax-ename->vla-object (car ent)) 'LB 'RT)
            (print (setq LB (vlax-safearray->list LB)))
            (print (setq RT (vlax-safearray->list RT)))
            (print (trans LB 0 1))
            (print (trans RT 0 1))
            (command "_rectang" (trans LB 0 1) (trans RT 0 1)) 

            ; coordinate control
            (command "_line" (trans LB 0 1) (trans RT 0 1) "")

            ; restore UCS
            (command "_ucs" "_r" "tmp")
            (command "_ucs" "_d" "tmp")
            ; (cd:ENV_RestEnvVariable systemEnv)
        )
    )
    (princ)
)

(c:MTextBorder)

 

mtb.lsp mtb.dwg

Edytowane przez perlon
Odnośnik do komentarza
Udostępnij na innych stronach

Dzień dobry,

czy może Pan określić pomiędzy jakimi dokładnie układami chciałby Pan przeliczyć obiekty?

Kiedyś do ZWGeo pisaliśmy moduł do konwersji elementów pomiędzy geodezyjnymi układami współrzędnych. Jeśli te układy mamy zaprogramowane to chętnie sprawdzimy jak zachowuje się konwersja.

 

Odnośnik do komentarza
Udostępnij na innych stronach

Jeżeli chodzi o transformacje to chciałbym obiekt narysowany w globalnym układzie w tzw. "zerze" przetransformować do punktu i płaszczyzny oraz rotacji innego obiektu znajdującego się gdzieś w przestrzeni 3D wskazując ten obiekt. Zadanie to wykonuje się pod spodem komendy "_ucs" "ob" niejako w odwrotnej kolejności tzn. najpierw ustawiam układ współrzędnych na obiekt a potem rysuje drugi obiekt. Chciałbym to jednak zrobić w bardziej elegancki sposób czyli generować od razu obiekty w przestrzeni 3D poprzez transformację węzłów obiektu który chcę wstawić odczytując układ odniesienia obiektu bazowego i do takiego układu transformować inny obiekt. To co do tej pory przeczytałem pokazuje że w AciveX muszę stworzyć macierz transformacji układu obiektu czyli ECS do układu globalnego WCS aby móc wykonać przeniesienie obiektu z płaszczyzny WCS do płaszczyzny ECS lub w czystym lisp'ie pobawić się w podmianę w encji stosownych par kropkowych 10, 50 i 210 być może jeszcze innych. Przy rotacji niestety kod dxf 50 zwraca rotację względem aktualnego UCS więc musiałbym jeszcze uwzględnić transformację tego kąta z ECS do UCS a następnie do WCS. Nie mam tego jeszcze dobrze poukładanego w głowie.  Proszę zwrócić uwagę że przywołany w pierwszym poście lisp prostokąt-obejmujacy rysuje ten prostokąt w WCS. Ja chciałbym znaleźć sposób na narysowanie go w jakimś innym układzie nieortogonalnym do WCS. I kolejne spostrzeżenie. vla-GetBoundingBox tak naprawdę podaje maksymalne i minimalne współrzędne ograniczające obiekt w globalnym układzie współrzędnych. Wskazuje box'a opisanego na obiekcie o ściankach zgodnych z WCS niezależnie od aktualnego UCS'a. Żeby narysować prawidłową ramkę obiektu gdzieś w przestrzeni to powinienem go przetransformować do WCS odczytać/narysować tą ramkę i ją przetransformować do ECS'a bo aktualny UCS może być zupełnie inny niż WCS i ECS. Ale się rozpisałem. Mam nadzieję że nie zagmatwałem.  

Edytowane przez perlon
Odnośnik do komentarza
Udostępnij na innych stronach

Temat jest dosyć złożony. Nie mam prostego rozwiązania, ale może podpowiedź pomoże.
Nie sprawdzałem i nie wiem czy to zadziała ale szukałbym w tym kierunku.
Z obiektu można odczytać wektor normalny.
Można też z wektora normalnego obliczyć macierz transformacji
https://math.stackexchange.com/questions/1956699/getting-a-transformation-matrix-from-a-normal-vector
Następnie można narysować co trzeba w WCS i transformować to obliczoną macierzą.

Prawdę mówiąc uważam, że jeśli rysowanie przez command działa i wystarczy, to opakowanie tego ładną funkcją wystarczy żeby i nie warto szukać w tym doskonałości elegancji. Może warto zamiast od razu rysować to tylko zczytać 3 punkty: środek, i kierunki X Y. A potem na tej podstawie zdefiniować tymczasowy UCS wykorzystywany do rysowania jeśli potrzeba narysować coś innego.

Odnośnik do komentarza
Udostępnij na innych stronach

Potrzebujesz:
1) (załadowanego) CADPL-Pack'a (wiadomo)
2) funkcji z Express Tools: acet-geom-mtxtbox (oprócz AutoCAD-a jest w BricsCAD-zie i GStar'ze. Nie wiem jak jest w ZwCAD-ie)
3) Poniższego kawałka kodu:
 

;;;  ramka MTEXTu (2024 by kojacek)
(defun C:MTEST (/ %e %d %p %o %z)
  (if
    (and
      (setq %e (car (entsel "\Wybierz MTEXT:")))
      (= "MTEXT" (cdr (assoc 0 (setq %d (entget %e)))))
    )
    (progn
      (setq %p (acet-geom-mtxtbox %d 0.0)
            %z (cdr (assoc 210 %d))
            %p (mapcar
                 '(lambda (%)
                    (trans % 1 %z)
                 ) %p
               )
      )
      (setq %o (cd:ACX_AddLWPolyline (cd:ACX_ASpace) %p t))
      (vla-TransformBy %o (cd:CON_TransMatrix 0))
    )
    (princ "\nZły wybór.")
  )
)

Z tego co na szybko przetestowałem, maluje prostokąt dla wskazanego MTEXT-u, niezależnie od aktywnego układu współrzednych. Funkcja acet-geom-mtxtbox, zwraca współrzędne prostokata opisującego rzeczywisty obszar MTEXT-u (porównaj z ramką MTEXT-u). Swego czasu poruszałem to tu: https://kojacek.wordpress.com/2017/10/08/wielkosc-obszaru-mtext-u/. Drugi argument funkcji (tutaj 0.0), to odsunięcie prostokąta. Pozwala to na rysowanie większego obramowania. 

Edytowane przez kojacek
Odnośnik do komentarza
Udostępnij na innych stronach

Akurat acet-geom-mtxtbox w zwcad działa. Szybsza metoda niż odczytywanie kodów dxf assoc'em. Jedynie co to mnie zastanowiło dlaczego mtext wstawiony w (0,0) daje taki wynik :

Command: (acet-geom-mtxtbox (entget (car (entsel))) 1)
Select object: ((-2.5 -14.1962 0.0) (21.9509 -14.1962 0.0) (21.9509 2.5 0.0) (-2.5 2.5 0.0))

Jak widać margines jest 2.5.

Ten sam obiekt z marginesem 0 daje takie dane :

Command: (acet-geom-mtxtbox (entget (car (entsel))) 0)
Select object: ((0.0 -11.6962 0.0) (19.4509 -11.6962 0.0) (19.4509 0.0 0.0) (0.0 0.0 0.0))

Jakaś zmienna środowiskowa to determinuje?

Edytowane przez perlon
Odnośnik do komentarza
Udostępnij na innych stronach

30 minut temu, perlon napisał:

Akurat acet-geom-mtxtbox w zwcad działa. Szybsza metoda niż odczytywanie kodów dxf assoc'em. Jedynie co to mnie zastanowiło dlaczego mtext wstawiony w (0,0) daje taki wynik :

Command: (acet-geom-mtxtbox (entget (car (entsel))) 1)
Select object: ((-2.5 -14.1962 0.0) (21.9509 -14.1962 0.0) (21.9509 2.5 0.0) (-2.5 2.5 0.0))

Jak widać margines jest 2.5.

Ten sam obiekt z marginesem 0 daje takie dane :

Command: (acet-geom-mtxtbox (entget (car (entsel))) 0)
Select object: ((0.0 -11.6962 0.0) (19.4509 -11.6962 0.0) (19.4509 0.0 0.0) (0.0 0.0 0.0))

Jakaś zmienna środowiskowa to determinuje?

WIdzę teraz, że odsunięcie ramki nie jest wyrażone w jednostkach, tylko jako jako współczynnik wysokości. Wartość 1 daje odsunięcie o wartości Height MTEXT-u. 

Odnośnik do komentarza
Udostępnij na innych stronach

W dniu 25.10.2024 o 20:19, kojacek napisał:

Potrzebujesz:
1) (załadowanego) CADPL-Pack'a (wiadomo)
2) funkcji z Express Tools: acet-geom-mtxtbox (oprócz AutoCAD-a jest w BricsCAD-zie i GStar'ze. Nie wiem jak jest w ZwCAD-ie)
3) Poniższego kawałka kodu:
[...]

Z tego co na szybko przetestowałem, maluje prostokąt dla wskazanego MTEXT-u, niezależnie od aktywnego układu współrzednych. Funkcja acet-geom-mtxtbox, zwraca współrzędne prostokata opisującego rzeczywisty obszar MTEXT-u (porównaj z ramką MTEXT-u). Swego czasu poruszałem to tu: https://kojacek.wordpress.com/2017/10/08/wielkosc-obszaru-mtext-u/. Drugi argument funkcji (tutaj 0.0), to odsunięcie prostokąta. Pozwala to na rysowanie większego obramowania. 

 acet-geom-mtxtbox zwraca obszar obramowania mtext  ale rzutuje go na płaszczyznę X-Y WCS a w przypadku kiedy MTEXT nie jest równoległy do tej płaszczyzny to obramowanie dostaje dziwnej translacji. Dlatego Postanowiłem ominąć ten problem poprzez transformację obiektu jak poniżej :

; ============================================================================================= ;
; c:MTextBox - enclose mtext in a box and place leader for callout                              ;
; --------------------------------------------------------------------------------------------- ;
; ©2024 by Tomasz Tkaczyk                                                                       ;
; ============================================================================================= ;

(load "CADPL-Pack-v1")
(load "TransMatrix")

(defun c:MTextBox ( / ent entName origin x-axis y-axis z-axis matrix obj)
	(if (and                                                                           
            (setq entName (car (entsel "Wybierz MTEXT:")))
            (= "MTEXT" (cdr (assoc 0 (setq ent (entget entName)))))
		)
        (progn
            (setq
                origin (cdr (assoc 10 ent))
                x-axis (cdr (assoc 11 ent))
                z-axis (cdr (assoc 210 ent))
                y-axis (cd:T3D_NormalVector '(0 0 0) z-axis x-axis)
                matrix (cd:T3D_TransformMatrix x-axis y-axis z-axis origin)
                obj (vlax-ename->vla-object entname)
            )
            (vla-TransformBy obj (vlax-tmatrix (cd:T3D_InvertMatrix matrix)))
            (vla-TransformBy
                (cd:ACX_AddLWPolyline (cd:ACX_ASpace) (acet-geom-mtxtbox (entget entname) 0) T)
                (vlax-tmatrix matrix)
            )
            (vla-TransformBy obj (vlax-tmatrix matrix))
        )
    )
)

Powyższe wymaga kilku funkcji do transformacji obiektów w przestrzeni. Zebrałem trochę kodu w krótką biblioteczkę

(princ "\nŁadowanie biblioteki TransMatrix............")

;;; ========================================================================================= ;
;;; TransMatrix.lsp                                                                           ;
;;; [2024-10-29] ©2024 by Tomasz Tkaczyk                                                      ;
;;; ========================================================================================= ;

; [T3D] ===================================================================================== ;
; c:UCSZDIR                   - Zwraca wektor normalny aktualnego lokalnego układu            ;
;                               współrzędnych                                                 ;
; cd:T3D_NormalizeVector      - Normalizuje odległość między punktami do wektora jednostkowego;
; cd:T3D_NormalVector         - Zwraca wektor normalny do płaszczyzny określonej              ;
;                               trzema punktami                                               ;
; cd:T3D_ASin                 - Zwraca arcus sinus kąta wyrażonego w radianach                ;
; cd:T3D_ACos                 - Zwraca arcus cosinus kąta wyrażonego w radianach              ;
; cd:T3D_Angle3PtsVC          - Zwraca kąt między odciankami p0-p1 p0-p2 (rachunek wektorowy) ;
; cd:T3D_Angle3PtsTC          - Zwraca kąt między odciankami p0-p1 p0-p2 (twierdzenie Carnota);
; cd:T3D_Elev                 - Zwraca elewację punktu nad płaszczyzną p0-p1-p2               ;
; cd:T3D_ProjectPt            - Zwraca punkt rzutowany na płaszczyznę p0-p1-p2                ;
; cd:T3D_TransformMatrix      - Zwraca macierz transformacji do układu x-y-z-origin           ;
; cd:T3D_InvertMatrix         - Zwraca macierz odwrotną do macieży transformacji              ;
; cd:T3D_CompositionTwoMatrices - Zwraca wynik mnożenia dwóch macierzy transformacji          ;
; =========================================================================================== ;




; =========================================================================================== ;
; Zwraca wektor normalny aktualnego lokalnego układu współrzędnych                            ;
; ------------------------------------------------------------------------------------------- ;
; (c:UCSZDIR)                                                                                 ;
; =========================================================================================== ;
(defun c:UCSZDIR ()
    (trans '(0 0 1) 1 0 T)
)

; =========================================================================================== ;
; Zwraca wektor jednostkowy odległości między dwoma punktami punktami                         ;
; p1 p2 - punkty w przestrzeni 3D                                                             ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_UnitVector p0 p1)                                                                   ;
; =========================================================================================== ;
(defun cd:T3D_UnitVector(p0 p1)
    (if (not (equal p0 p1 1e-009))
        (mapcar
            '(lambda (x) (/ x (distance p0 p1)))
            (mapcar '- p1 p0)
        )
    )
)

; =========================================================================================== ;
; Zwraca wektor normalny do płaszczyzny określonej trzema punktami                            ;
; w przestrzeni zgodnej z reguła prawej dłoni                                                 ;
; p0 p1 p2 - punkty w przestrzeni 3D                                                          ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_NormalVector p0 p1 p2)                                                              ;
; =========================================================================================== ;
(defun cd:T3D_NormalVector (p0 p1 p2 / normal)
    (cond
        (
            (inters p0 p1 p0 p2)
            (foreach p	'(p1 p2) (set p (mapcar '- (eval p) p0)))
            (setq 
                normal (list (- (* (cadr p1) (caddr p2)) (* (caddr p1) (cadr p2)))
                           (- (* (caddr p1) (car p2)) (* (car p1) (caddr p2)))
                           (- (* (car p1) (cadr p2)) (* (cadr p1) (car p2)))
                     )
                normal (mapcar '(lambda (x) (* x (/ 1 (distance '(0 0 0) normal)))) normal)
            )
        )
    )
)

; =========================================================================================== ;
; Zwraca arcus sinus kąta wyrażonego w radianach                                              ;
; ------------------------------------------------------------------------------------------- ;
; (ccd:T3D_ASin ang)                                                                          ;
; =========================================================================================== ;
(defun cd:T3D_ASin (ang)
  (if (<= -1 ang 1)
    (atan ang (sqrt (- 1 (expt ang 2))))
  )
)

; =========================================================================================== ;
; Zwraca arcus cosinus kąta wyrażonego w radianach                                            ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_ACos ang)                                                                           ;
; =========================================================================================== ;
(defun cd:T3D_ACos (ang)
  (if (<= -1 ang 1)
    (atan (sqrt (- 1 (expt ang 2))) ang)
  )
)

; =========================================================================================== ;
; Zwraca kąt między odciankami p0-p1 a p0-p2 (rachunek wektorowy)                             ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_Angle3PtsVC p0 p1 p2)                                                               ;
; =========================================================================================== ;
(defun cd:T3D_Angle3PtsVC (p0 p1 p2 / v1 v2)
  (if (and
	(setq v1 (cd:T3D_UnitVector p0 p1))
	(setq v2 (cd:T3D_UnitVector p0 p2))
      )
    (cond
      ((equal v1 v2 1e-009) 0.0)
      ((equal v1 (mapcar '- v2) 1e-009) pi)
      (T (* 2 (cd:T3D_ASin (/ (distance v1 v2) 2))))
    )
  )
)

; =========================================================================================== ;
; Zwraca kąt między odciankami p0-p1 a p0-p2 (twierdzenie Carnota)                            ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_Angle3PtsTC p0 p1 p2)                                                               ;
; =========================================================================================== ;
(defun cd:T3D_Angle3PtsTC (p0 p1 p2 / d1 d2 d3)
    (setq	
        d1 (distance p0 p1)
        d2 (distance p0 p2)
        d3 (distance p1 p2)
    )
    (if (and (not (zerop d1)) (not (zerop d2)))
        (cd:T3D_ACos 
            (/ (+ (* d1 d1) (* d2 d2) (- (* d3 d3))) (* 2 d1 d2))
        )
    )
)

; =========================================================================================== ;
; Zwraca elewację punktu nad płaszczyzną p0-p1-p2                                             ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_Elev pt p0 p1 p2)                                                                   ;
; =========================================================================================== ;
(defun cd:T3D_Elev (pt p0 p1 p2)
    (* (cos (cd:T3D_Angle3PtsVC p0 (mapcar '+ p0 (cd:T3D_NormalVector p0 p1 p2)) pt))
        (distance p0 pt)
    )
)

; =========================================================================================== ;
; Zwraca punkt rzutowany na płaszczyznę p0-p1-p2                                              ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_ProjectPt pt p0 p1 p2)                                                              ;
; =========================================================================================== ;
(defun cd:3D_ProjectPt (pt p0 p2 p3)
  (mapcar '-
	  pt
	  (mapcar '(lambda (x) (* x (cd:T3D_Elev pt p0 p1 p2)))
		  (cd:T3D_NormalVector p0 p1 p2)
	  )
  )
)

; =========================================================================================== ;
; Zwraca macież transformacji do układu x-y-z-origin                                          ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_TransformMatrix x-axis y-axis z-axis origin)                                        ;
; =========================================================================================== ;
(defun cd:T3D_TransformMatrix (x-axis y-axis z-axis origin)
  (list
    (list (nth 0 x-axis) (nth 0 y-axis) (nth 0 z-axis) (nth 0 origin))
    (list (nth 1 x-axis) (nth 1 y-axis) (nth 1 z-axis) (nth 1 origin))
    (list (nth 2 x-axis) (nth 2 y-axis) (nth 2 z-axis) (nth 2 origin))
    (list 0 0 0 1)
  )
)

; =========================================================================================== ;
; Zwraca macież odwrotną do macierzy transformacji                                            ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_InvertMatrix matrix)                                                                ;
; =========================================================================================== ;
(defun cd:T3D_InvertMatrix( tmatrix / m00 m01 m02 m03 m10 m11 m12 m13 m20 m21 m22 m23 m30 m31 m32 m33
                                      inv00 inv01 inv02 inv10 inv11 inv12 inv20 inv21 inv22)
    ;; Pobierz elementy macierzy z listy list
    (setq 
        m00 (nth 0 (nth 0 tmatrix))  m01 (nth 1 (nth 0 tmatrix))  m02 (nth 2 (nth 0 tmatrix))  m03 (nth 3 (nth 0 tmatrix))
        m10 (nth 0 (nth 1 tmatrix))  m11 (nth 1 (nth 1 tmatrix))  m12 (nth 2 (nth 1 tmatrix))  m13 (nth 3 (nth 1 tmatrix))
        m20 (nth 0 (nth 2 tmatrix))  m21 (nth 1 (nth 2 tmatrix))  m22 (nth 2 (nth 2 tmatrix))  m23 (nth 3 (nth 2 tmatrix))
        m30 (nth 0 (nth 3 tmatrix))  m31 (nth 1 (nth 3 tmatrix))  m32 (nth 2 (nth 3 tmatrix))  m33 (nth 3 (nth 3 tmatrix))
    )

    ;; Oblicz transpozycję macierzy rotacji (górna lewa 3x3)
    (setq 
        inv00 m00 inv01 m10 inv02 m20
        inv10 m01 inv11 m11 inv12 m21
        inv20 m02 inv21 m12 inv22 m22
    )

    ;; Oblicz odwrotny wektor translacji
    (setq 
        inv03 (- (+ (* inv00 m03) (* inv01 m13) (* inv02 m23)))
        inv13 (- (+ (* inv10 m03) (* inv11 m13) (* inv12 m23)))
        inv23 (- (+ (* inv20 m03) (* inv21 m13) (* inv22 m23)))
    )

    ;; Skonstruuj macierz wynikową
    (list
        (list inv00 inv01 inv02 inv03)
        (list inv10 inv11 inv12 inv13)
        (list inv20 inv21 inv22 inv23)
        (list 0 0 0 1)
    )
)

; =========================================================================================== ;
; Zwraca wynik mnożenia dwóch macierzy transformacji                                          ;
; ------------------------------------------------------------------------------------------- ;
; (cd:T3D_CompositionTwoMatrices matrixA matrixB)                                             ;
; =========================================================================================== ;
(defun cd:T3D_CompositionTwoMatrices (A B)
    (list
        (list 
            (+ (* (nth 0 (nth 0 A)) (nth 0 (nth 0 B))) (* (nth 1 (nth 0 A)) (nth 0 (nth 1 B))) (* (nth 2 (nth 0 A)) (nth 0 (nth 2 B))))
            (+ (* (nth 0 (nth 0 A)) (nth 1 (nth 0 B))) (* (nth 1 (nth 0 A)) (nth 1 (nth 1 B))) (* (nth 2 (nth 0 A)) (nth 1 (nth 2 B))))
            (+ (* (nth 0 (nth 0 A)) (nth 2 (nth 0 B))) (* (nth 1 (nth 0 A)) (nth 2 (nth 1 B))) (* (nth 2 (nth 0 A)) (nth 2 (nth 2 B))))
            (+ (* (nth 0 (nth 0 A)) (nth 3 (nth 0 B))) (* (nth 1 (nth 0 A)) (nth 3 (nth 1 B))) (* (nth 2 (nth 0 A)) (nth 3 (nth 2 B))) (nth 3 (nth 0 A)))
        )
        (list 
            (+ (* (nth 0 (nth 1 A)) (nth 0 (nth 0 B))) (* (nth 1 (nth 1 A)) (nth 0 (nth 1 B))) (* (nth 2 (nth 1 A)) (nth 0 (nth 2 B))))
            (+ (* (nth 0 (nth 1 A)) (nth 1 (nth 0 B))) (* (nth 1 (nth 1 A)) (nth 1 (nth 1 B))) (* (nth 2 (nth 1 A)) (nth 1 (nth 2 B))))
            (+ (* (nth 0 (nth 1 A)) (nth 2 (nth 0 B))) (* (nth 1 (nth 1 A)) (nth 2 (nth 1 B))) (* (nth 2 (nth 1 A)) (nth 2 (nth 2 B))))
            (+ (* (nth 0 (nth 1 A)) (nth 3 (nth 0 B))) (* (nth 1 (nth 1 A)) (nth 3 (nth 1 B))) (* (nth 2 (nth 1 A)) (nth 3 (nth 2 B))) (nth 3 (nth 1 A)))
        )
        (list 
            (+ (* (nth 0 (nth 2 A)) (nth 0 (nth 0 B))) (* (nth 1 (nth 2 A)) (nth 0 (nth 1 B))) (* (nth 2 (nth 2 A)) (nth 0 (nth 2 B))))
            (+ (* (nth 0 (nth 2 A)) (nth 1 (nth 0 B))) (* (nth 1 (nth 2 A)) (nth 1 (nth 1 B))) (* (nth 2 (nth 2 A)) (nth 1 (nth 2 B))))
            (+ (* (nth 0 (nth 2 A)) (nth 2 (nth 0 B))) (* (nth 1 (nth 2 A)) (nth 2 (nth 1 B))) (* (nth 2 (nth 2 A)) (nth 2 (nth 2 B))))
            (+ (* (nth 0 (nth 2 A)) (nth 3 (nth 0 B))) (* (nth 1 (nth 2 A)) (nth 3 (nth 1 B))) (* (nth 2 (nth 2 A)) (nth 3 (nth 2 B))) (nth 3 (nth 2 A)))
        )
        (list 0 0 0 1)
    )
)

(princ " Załadowane")
(princ "\nTransMatrix v.0.1 ©2024 by Tomasz Tkaczyk")
(princ "\nbased from gile on https://www.theswamp.org/index.php?topic=11561.0")
(princ)

 Powyższe otwiera drogę do modyfikacji programu do rysowania obramowania grupy obiektów dowolnie zorientowanych w przestrzeni na płaszczyźnie X-Y aktualnego UCS'a również dowolnie zorientowanego z uwzględnieniem również obiektów typu MTEXT.

 

Edytowane przez dmatusz3
Na prośbę autora
Odnośnik do komentarza
Udostępnij na innych stronach

Niestety powyższe nie działa prawidłowo w każdym przypadku orientacji UCS i samego MText. Uzupełniłem kod o odpowiednie translacje żeby rozwiązać, albo raczej ominąć problem. Ponieważ nie mogę już edytować poprzedniego postu załączam kod ponownie. Zmieniłem również definicję dwóch funkcji z TransMatrix.lsp. Dlatego zamieszczam pliki ponownie z prośbą do admina o usunięcie poprzednich wersji. Dorzuciłem również pewien test funkcji acet-geom-mtxtbox oraz plik dwg, który obrazuje problem jej wykorzystania wraz z nagraniem testu.image.thumb.gif.cd973a6d7d8f4680f747f2392dcfaa53.gif

Test rysuje proste linie w przestrzeni żeby uniknąć narzutu polilinii. Czy jest gdzieś dostępna dokumentacja funkcji acet-geom-mtxtbox bo powyższe zrobiło mii nieco zamieszania w głowie.

MTextBox.lsp TransMatrix.lsp

mtb.dwg

Edytowane przez perlon
Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie