[FIX] Weltposition verpackter Separator_SP-Symbole bei gekippten Ketten
ssg-collect-nested-inserts-rel/csv:sep-proxies-erzeugen nahmen bislang eine reine Z-Drehung ohne OCS-/Extrusionsrichtung an. Fuer die um den Gefaelle-/ Neigungswinkel gekippte Staustrecke/Separator-Kette (Gefaellestrecke.lsp, vf_standard.lsp) ist das falsch: die eingebettete Separator_SP-Weltposition blieb dadurch unabhaengig von der gewaehlten Fahrtrichtung eingefroren. Fix generalisiert die Rotationskomposition auf volle 3x3-Matrizen (Arbitrary Axis Algorithm fuer die Extrusion, neue mat3-*-Helfer in ssg_core.lsp statt vf_core.lsp, da ssg_core immer vor jedem Feature-Modul geladen ist). Fuer flache Elemente (Extrusion (0 0 1)) reduziert sich das exakt auf die alte reine Z-Drehung - kein Verhaltensunterschied dort. Verifiziert per Python/ezdxf-Nachbau des neuen Algorithmus gegen die drei real gebauten Testzeichnungen (data/gf.dxf, data/gf_north.dxf, data/gf_south.dxf): liefert jetzt fuer alle drei Fahrtrichtungen exakt die unabhaengig berechnete Grundwahrheit statt eines eingefrorenen Werts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+52
-22
@@ -630,9 +630,9 @@
|
||||
;; Kopie gesetzt werden kann (csv:sep-proxies-zuordnung-setzen). Die
|
||||
;; proxy-enames dienen ausserdem csv:sep-proxies-loeschen nach dem Export.
|
||||
(defun csv:sep-proxies-erzeugen ( / ms ss-all i ename ed bname nested pt rotation
|
||||
psx psy psz c si rec nested-ent nested-bname
|
||||
local-pt nested-rot lx ly lz world-pt
|
||||
block-obj proxy-liste)
|
||||
extrusion0 R0 psx psy psz rec nested-ent nested-bname
|
||||
local-pt R-nested R-final scaled-pt rot-pt world-pt
|
||||
T4 block-obj xform-fehler proxy-liste)
|
||||
(setq ss-all (ssget "X" (list (cons 0 "INSERT"))))
|
||||
(if ss-all
|
||||
(progn
|
||||
@@ -649,25 +649,43 @@
|
||||
(if nested
|
||||
(progn
|
||||
(setq pt (cdr (assoc 10 ed)))
|
||||
(if (null (caddr pt)) (setq pt (list (car pt) (cadr pt) 0.0)))
|
||||
(setq rotation (cond ((cdr (assoc 50 ed))) (0.0)))
|
||||
;; Extrusion des Wrapper-INSERTs selbst beruecksichtigen statt
|
||||
;; reine Z-Drehung anzunehmen - GF_n/VF_n stehen zwar bisher immer
|
||||
;; flach (Extrusion (0 0 1)), aber mat3-from-normal-rotation
|
||||
;; reduziert sich dafuer ohnehin exakt auf Rz(rotation), kostet
|
||||
;; also nichts und macht den Code robust falls sich das aendert.
|
||||
(setq extrusion0 (cond ((cdr (assoc 210 ed))) ('(0.0 0.0 1.0))))
|
||||
(setq R0 (mat3-from-normal-rotation extrusion0 rotation))
|
||||
(setq psx (cond ((cdr (assoc 41 ed))) (1.0)))
|
||||
(setq psy (cond ((cdr (assoc 42 ed))) (1.0)))
|
||||
(setq psz (cond ((cdr (assoc 43 ed))) (1.0)))
|
||||
(setq c (cos rotation) si (sin rotation))
|
||||
(foreach rec nested
|
||||
(setq nested-ent (nth 0 rec))
|
||||
(setq local-pt (nth 1 rec))
|
||||
(setq nested-rot (nth 2 rec))
|
||||
(setq R-nested (nth 2 rec))
|
||||
(setq nested-bname (cdr (assoc 2 (entget nested-ent))))
|
||||
(setq lx (* psx (car local-pt))
|
||||
ly (* psy (cadr local-pt))
|
||||
lz (* psz (caddr local-pt)))
|
||||
(setq world-pt
|
||||
(list (+ (car pt) (- (* lx c) (* ly si)))
|
||||
(+ (cadr pt) (+ (* lx si) (* ly c)))
|
||||
(+ (cond ((caddr pt)) (0.0)) lz)))
|
||||
;; Rotation fuer vla-InsertBlock in RADIANT (ActiveX-Konvention,
|
||||
;; anders als der Grad-Winkel von "command _.INSERT").
|
||||
(setq scaled-pt (list (* psx (car local-pt))
|
||||
(* psy (cadr local-pt))
|
||||
(* psz (caddr local-pt))))
|
||||
(setq rot-pt (mat3-mul-vec3 R0 scaled-pt))
|
||||
(setq world-pt (list (+ (car pt) (car rot-pt))
|
||||
(+ (cadr pt) (cadr rot-pt))
|
||||
(+ (caddr pt) (caddr rot-pt))))
|
||||
(setq R-final (mat3-mul-mat3 R0 R-nested))
|
||||
;; Volle 3D-Orientierung statt bisher nur eines Z-Drehwinkels:
|
||||
;; ein einzelner Skalar-Drehwinkel kann eine Kippung ausserhalb
|
||||
;; der XY-Ebene (Gefaellestrecke-/VF-Neigung) gar nicht
|
||||
;; darstellen. Deshalb - wie insert-block-ks-to-ks (vf_core.lsp)
|
||||
;; - am Ursprung mit Rotation=0 einfuegen und die komplette
|
||||
;; Lage (Drehung UND Verschiebung) in EINER vla-TransformBy
|
||||
;; anwenden, statt Rotation als vla-InsertBlock-Parameter.
|
||||
(setq T4 (vlax-tmatrix
|
||||
(list (list (car (car R-final)) (cadr (car R-final)) (caddr (car R-final)) (car world-pt))
|
||||
(list (car (cadr R-final)) (cadr (cadr R-final)) (caddr (cadr R-final)) (cadr world-pt))
|
||||
(list (car (caddr R-final)) (cadr (caddr R-final)) (caddr (caddr R-final)) (caddr world-pt))
|
||||
(list 0.0 0.0 0.0 1.0))))
|
||||
;; Gekapselt, weil hier - anders als beim frueheren festen
|
||||
;; 1.0/1.0/1.0 - die tatsaechlichen Skalierungsfaktoren
|
||||
;; durchgereicht werden: ein einzelner Sonderfall (entartete
|
||||
@@ -676,17 +694,29 @@
|
||||
;; eine Kopie ausfallen lassen - mit Meldung, welcher Block.
|
||||
(setq block-obj
|
||||
(vl-catch-all-apply 'vla-InsertBlock
|
||||
(list ms (vlax-3D-point world-pt) nested-bname
|
||||
(list ms (vlax-3D-point '(0.0 0.0 0.0)) nested-bname
|
||||
(csv:skalierung-oder-eins (* psx (nth 3 rec)))
|
||||
(csv:skalierung-oder-eins (* psy (nth 4 rec)))
|
||||
(csv:skalierung-oder-eins (* psz (nth 5 rec)))
|
||||
(+ rotation nested-rot))))
|
||||
(if (vl-catch-all-error-p block-obj)
|
||||
(princ (ssg-textf "exp-sep-proxy-fehler"
|
||||
(list nested-bname bname
|
||||
(vl-catch-all-error-message block-obj))))
|
||||
(setq proxy-liste
|
||||
(cons (cons (vlax-vla-object->ename block-obj) ename) proxy-liste))
|
||||
0.0)))
|
||||
(cond
|
||||
((vl-catch-all-error-p block-obj)
|
||||
(princ (ssg-textf "exp-sep-proxy-fehler"
|
||||
(list nested-bname bname
|
||||
(vl-catch-all-error-message block-obj)))))
|
||||
(t
|
||||
(setq xform-fehler (vl-catch-all-apply 'vla-TransformBy (list block-obj T4)))
|
||||
(if (vl-catch-all-error-p xform-fehler)
|
||||
(progn
|
||||
(princ (ssg-textf "exp-sep-proxy-fehler"
|
||||
(list nested-bname bname
|
||||
(vl-catch-all-error-message xform-fehler))))
|
||||
(vl-catch-all-apply 'vla-Delete (list block-obj))
|
||||
)
|
||||
(setq proxy-liste
|
||||
(cons (cons (vlax-vla-object->ename block-obj) ename) proxy-liste))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
+159
-22
@@ -201,6 +201,112 @@
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; 3x3-VEKTOR-/MATRIXHELFER (allgemein, dependency-frei)
|
||||
;; ------------------------------------------------------------
|
||||
;; Hier statt in vf_core.lsp, weil ssg-collect-nested-inserts-rel (weiter
|
||||
;; unten in diesem Modul) sie ebenfalls braucht und dieses Modul IMMER vor
|
||||
;; jedem Feature-Modul (inkl. vf_core.lsp) geladen ist - siehe MNL-Ladeliste.
|
||||
;; vf_core.lsp (insert-block-ks-to-ks/insert-block-mixed-to-ks) nutzt
|
||||
;; dieselben Definitionen unveraendert weiter.
|
||||
|
||||
;; Vektorkreuzprodukt a x b
|
||||
(defun vec3-cross (a b)
|
||||
(list (- (* (cadr a)(caddr b)) (* (caddr a)(cadr b)))
|
||||
(- (* (caddr a)(car b)) (* (car a)(caddr b)))
|
||||
(- (* (car a)(cadr b)) (* (cadr a)(car b)))))
|
||||
|
||||
;; Vektor auf Einheitslaenge normieren
|
||||
(defun vec3-normalize (v / len)
|
||||
(setq len (vec-length v))
|
||||
(if (> len 1e-10)
|
||||
(list (/ (car v) len) (/ (cadr v) len) (/ (caddr v) len))
|
||||
'(1.0 0.0 0.0)))
|
||||
|
||||
;; 3x3-Rotationsmatrix (Zeilenliste) mal 3D-Vektor
|
||||
(defun mat3-mul-vec3 (R v / r0 r1 r2)
|
||||
(setq r0 (car R) r1 (cadr R) r2 (caddr R))
|
||||
(list (+ (* (car r0)(car v)) (* (cadr r0)(cadr v)) (* (caddr r0)(caddr v)))
|
||||
(+ (* (car r1)(car v)) (* (cadr r1)(cadr v)) (* (caddr r1)(caddr v)))
|
||||
(+ (* (car r2)(car v)) (* (cadr r2)(cadr v)) (* (caddr r2)(caddr v)))))
|
||||
|
||||
;; Rotationsmatrix R sodass: R*xe=xt, R*ye=yt, R*ze=zt
|
||||
;; (xt yt zt) = Ziel-Achsen; (xe ye ze) = Quell-Achsen (je normierte Einheitsvektoren)
|
||||
;; Formel: R = M_target * M_source^T
|
||||
;; R[i][j] = xt[i]*xe[j] + yt[i]*ye[j] + zt[i]*ze[j]
|
||||
(defun mat3-from-frames (xt yt zt xe ye ze)
|
||||
(list
|
||||
(list (+ (* (car xt)(car xe)) (* (car yt)(car ye)) (* (car zt)(car ze)))
|
||||
(+ (* (car xt)(cadr xe)) (* (car yt)(cadr ye)) (* (car zt)(cadr ze)))
|
||||
(+ (* (car xt)(caddr xe)) (* (car yt)(caddr ye)) (* (car zt)(caddr ze))))
|
||||
(list (+ (* (cadr xt)(car xe)) (* (cadr yt)(car ye)) (* (cadr zt)(car ze)))
|
||||
(+ (* (cadr xt)(cadr xe)) (* (cadr yt)(cadr ye)) (* (cadr zt)(cadr ze)))
|
||||
(+ (* (cadr xt)(caddr xe)) (* (cadr yt)(caddr ye)) (* (cadr zt)(caddr ze))))
|
||||
(list (+ (* (caddr xt)(car xe)) (* (caddr yt)(car ye)) (* (caddr zt)(car ze)))
|
||||
(+ (* (caddr xt)(cadr xe)) (* (caddr yt)(cadr ye)) (* (caddr zt)(cadr ze)))
|
||||
(+ (* (caddr xt)(caddr xe)) (* (caddr yt)(caddr ye)) (* (caddr zt)(caddr ze))))))
|
||||
|
||||
;; --- 3x3-Matrizenprodukt A*B (beide als Zeilenlisten wie mat3-from-frames) ---
|
||||
;; Spalten von B einzeln mit A multiplizieren (mat3-mul-vec3), Ergebnis-Matrix
|
||||
;; aus den 3 Ergebnis-Spalten wieder ueber mat3-from-frames zusammensetzen
|
||||
;; (mit Einheitsvektoren als Quell-Achsen baut das eine Matrix AUS Spalten -
|
||||
;; siehe mat3-from-normal-rotation, das denselben Trick nutzt).
|
||||
(defun mat3-mul-mat3 (A B / b-col0 b-col1 b-col2)
|
||||
(setq b-col0 (list (caar B) (car (cadr B)) (car (caddr B))))
|
||||
(setq b-col1 (list (cadar B) (cadr (cadr B)) (cadr (caddr B))))
|
||||
(setq b-col2 (list (caddar B) (caddr (cadr B)) (caddr (caddr B))))
|
||||
(mat3-from-frames
|
||||
(mat3-mul-vec3 A b-col0) (mat3-mul-vec3 A b-col1) (mat3-mul-vec3 A b-col2)
|
||||
'(1.0 0.0 0.0) '(0.0 1.0 0.0) '(0.0 0.0 1.0))
|
||||
)
|
||||
|
||||
;; --- OCS-Basis (Arbitrary Axis Algorithm) aus einer Extrusionsrichtung ---
|
||||
;; normal = Extrusionsvektor (DXF-Gruppe 210/220/230, Laenge beliebig).
|
||||
;; Rueckgabe: (ax ay az) - normierte OCS-Achsen, az = normiertes normal.
|
||||
;; Standardalgorithmus (Autodesk "Arbitrary Axis Algorithm"): Referenzachse
|
||||
;; ist Welt-Y, wenn normal nahe der Welt-Z-Achse liegt, sonst Welt-Z - damit
|
||||
;; bleibt ax*ay*az immer ein wohldefiniertes, rechtshaendiges Dreibein, auch
|
||||
;; wenn normal selbst (fast) mit der jeweiligen Referenzachse zusammenfaellt.
|
||||
(defun mat3-ocs-basis (normal / n wy-ref ax ay)
|
||||
(setq n (vec3-normalize normal))
|
||||
(setq wy-ref
|
||||
(if (and (< (abs (car n)) (/ 1.0 64.0)) (< (abs (cadr n)) (/ 1.0 64.0)))
|
||||
'(0.0 1.0 0.0)
|
||||
'(0.0 0.0 1.0)))
|
||||
(setq ax (vec3-normalize (vec3-cross wy-ref n)))
|
||||
(setq ay (vec3-normalize (vec3-cross n ax)))
|
||||
(list ax ay n)
|
||||
)
|
||||
|
||||
;; --- OCS-Basis als 3x3-Matrix (Spalten = ax ay az aus mat3-ocs-basis) ---
|
||||
;; Rechnet einen OCS-lokalen Punkt/Vektor (z.B. die rohe INSERT-Gruppe 10
|
||||
;; eines gekippten Elements) in echte lokale Koordinaten der Elternebene um:
|
||||
;; (mat3-mul-vec3 (mat3-ocs-matrix normal) ocs-punkt).
|
||||
(defun mat3-ocs-matrix (normal / basis)
|
||||
(setq basis (mat3-ocs-basis normal))
|
||||
(mat3-from-frames (car basis) (cadr basis) (caddr basis)
|
||||
'(1.0 0.0 0.0) '(0.0 1.0 0.0) '(0.0 0.0 1.0))
|
||||
)
|
||||
|
||||
;; --- Reine Z-Drehungsmatrix Rz(winkel), winkel in Radiant ---
|
||||
(defun mat3-rz (winkel / c s)
|
||||
(setq c (cos winkel) s (sin winkel))
|
||||
(mat3-from-frames (list c s 0.0) (list (- s) c 0.0) '(0.0 0.0 1.0)
|
||||
'(1.0 0.0 0.0) '(0.0 1.0 0.0) '(0.0 0.0 1.0))
|
||||
)
|
||||
|
||||
;; --- Volle 3x3-Rotationsmatrix aus Extrusion + Drehwinkel (DXF-Gruppen 210/50) ---
|
||||
;; normal = Extrusionsvektor, rotation = Drehwinkel in Radiant.
|
||||
;; = OCS-Basis(normal) * Rz(rotation): erst die eigene Z-Drehung IN der
|
||||
;; (evtl. gekippten) OCS-Ebene, dann diese Ebene selbst in die Elternebene
|
||||
;; kippen. Fuer normal=(0 0 1) ist mat3-ocs-matrix die Einheitsmatrix, das
|
||||
;; Ergebnis reduziert sich also exakt auf Rz(rotation) - fuer bereits flache
|
||||
;; Elemente aendert sich damit nichts am bisherigen Verhalten.
|
||||
(defun mat3-from-normal-rotation (normal rotation)
|
||||
(mat3-mul-mat3 (mat3-ocs-matrix normal) (mat3-rz rotation))
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; BENUTZER-ABFRAGEN
|
||||
;; ------------------------------------------------------------
|
||||
@@ -960,13 +1066,14 @@
|
||||
;; steckt.
|
||||
;;
|
||||
;; Rueckgabe: Liste von Treffer-Records, oder nil. Ein Record ist
|
||||
;; (ename (x y z) rot-rad sx sy sz)
|
||||
;; (ename (x y z) R sx sy sz)
|
||||
;; mit der Platzierung des Treffers RELATIV zur abgefragten Blockdefinition
|
||||
;; bname - ueber alle Verschachtelungsebenen hinweg aufsummiert (Position,
|
||||
;; Z-Drehung und Skalierung). Der Aufrufer muss also nur noch die Platzierung
|
||||
;; des top-level INSERT daraufrechnen. Der rohe Einfuegepunkt aus
|
||||
;; (entget ename) ist bei mehr als einer Ebene NICHT verwendbar - er gilt nur
|
||||
;; innerhalb der unmittelbaren Zwischen-Blockdefinition.
|
||||
;; volle 3D-Rotationsmatrix R und Skalierung). Der Aufrufer muss also nur
|
||||
;; noch die Platzierung des top-level INSERT daraufrechnen. Der rohe
|
||||
;; Einfuegepunkt aus (entget ename) ist bei mehr als einer Ebene NICHT
|
||||
;; verwendbar - er gilt nur innerhalb der unmittelbaren Zwischen-
|
||||
;; Blockdefinition.
|
||||
;;
|
||||
;; Kein Selection-Set: die Entities sind nicht Space-resident und damit fuer
|
||||
;; ssadd nicht sicher verwendbar. Sie bleiben ueber entget normal lesbar
|
||||
@@ -974,30 +1081,47 @@
|
||||
;; eigene Bounding-Box (vla-getboundingbox) liefert fuer sie keine sinnvollen
|
||||
;; Weltkoordinaten.
|
||||
(defun ssg-collect-nested-inserts (bname pattern)
|
||||
(ssg-collect-nested-inserts-rel bname pattern '(0.0 0.0 0.0) 0.0 1.0 1.0 1.0)
|
||||
(ssg-collect-nested-inserts-rel bname pattern '(0.0 0.0 0.0)
|
||||
'((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
|
||||
1.0 1.0 1.0)
|
||||
)
|
||||
|
||||
;; --- Rekursions-Rumpf mit mitgefuehrter Platzierung ---
|
||||
;; basis-pt/basis-rot/bsx/bsy/bsz = Platzierung der gerade durchsuchten
|
||||
;; basis-pt/basis-R/bsx/bsy/bsz = Platzierung der gerade durchsuchten
|
||||
;; Blockdefinition im Koordinatensystem des URSPRUENGLICH abgefragten Blocks.
|
||||
;; Auf jeder Ebene wird der Einfuegepunkt des Sub-INSERT erst mit der
|
||||
;; Skalierung, dann mit der Drehung der Ebene darueber verrechnet und
|
||||
;; Skalierung, dann mit der Rotation der Ebene darueber verrechnet und
|
||||
;; aufaddiert - genau das fehlte frueher: die Rekursion gab die Entities
|
||||
;; tieferer Ebenen mit ihrer ROH-Position aus der jeweiligen Zwischen-
|
||||
;; Blockdefinition zurueck. Zwei Separatoren, die in zwei verschieden
|
||||
;; platzierten Zwischenbloecken an derselben lokalen Stelle sitzen, landeten
|
||||
;; dadurch auf exakt derselben Weltposition (und damit beim falschen Carrier).
|
||||
;;
|
||||
;; Modellannahme wie im uebrigen Export (csv:local-to-world): reine
|
||||
;; Z-Drehung, keine OCS-/Extrusionsrichtung. Fuer die Wrapper-Ketten
|
||||
;; VF_n/GF_n/KREISEL_n trifft das zu.
|
||||
(defun ssg-collect-nested-inserts-rel (bname pattern basis-pt basis-rot bsx bsy bsz
|
||||
;; basis-R ist eine VOLLE 3x3-Rotationsmatrix (mat3-* oben in diesem Modul),
|
||||
;; keine reine Z-Drehung mehr: ein Sub-INSERT, dessen Extrusionsrichtung
|
||||
;; (DXF-Gruppe 210) von der Welt-Z-Achse abweicht - z.B. die um den
|
||||
;; Gefaellewinkel gekippte Staustrecke/Separator-Kette in
|
||||
;; Gefaellestrecke.lsp/vf_standard.lsp (ssg-rot-matrix-zy, Rz(hz)*Ry(-vert))
|
||||
;; - hat seinen eigenen Einfuegepunkt (Gruppe 10) NICHT in den gewoehnlichen
|
||||
;; lokalen XYZ-Koordinaten der Elterndefinition, sondern relativ zu SEINER
|
||||
;; EIGENEN, gekippten OCS-Ebene (Arbitrary Axis Algorithm). Die fruehere
|
||||
;; reine Z-Drehung ignorierte das komplett und lieferte fuer gekippte Ketten
|
||||
;; einen falschen, von der tatsaechlichen Fahrtrichtung unabhaengigen
|
||||
;; ("eingefrorenen") Weltpunkt. mat3-ocs-matrix wandelt die rohe OCS-lokale
|
||||
;; Gruppe-10 in echte lokale Koordinaten um, bevor sie mit der Eltern-
|
||||
;; Rotation weiterverrechnet wird; mat3-from-normal-rotation liefert die
|
||||
;; volle 3D-Orientierung des Sub-INSERTs selbst (fuer die naechste
|
||||
;; Rekursionsebene bzw. den Treffer-Record). Fuer Extrusion=(0 0 1) (der
|
||||
;; Normalfall, z.B. Kreisel/Eckrad) reduziert sich beides exakt auf die alte
|
||||
;; reine Z-Drehung - unveraendertes Verhalten dort.
|
||||
(defun ssg-collect-nested-inserts-rel (bname pattern basis-pt basis-R bsx bsy bsz
|
||||
/ blk-tbl sub-ent sub-ed sub-bname loc-pt
|
||||
rot sx sy sz c si lx ly lz wx wy wz result)
|
||||
extrusion rot sx sy sz ocs-mat loc-pt-real
|
||||
scaled-pt rot-pt R-local R-world world-pt
|
||||
result)
|
||||
(setq blk-tbl (tblsearch "BLOCK" bname))
|
||||
(if blk-tbl
|
||||
(progn
|
||||
(setq c (cos basis-rot) si (sin basis-rot))
|
||||
(setq sub-ent (entnext (cdr (assoc -2 blk-tbl))))
|
||||
(while sub-ent
|
||||
(setq sub-ed (entget sub-ent))
|
||||
@@ -1005,23 +1129,36 @@
|
||||
(progn
|
||||
(setq sub-bname (cdr (assoc 2 sub-ed)))
|
||||
(setq loc-pt (cdr (assoc 10 sub-ed)))
|
||||
(if (null (caddr loc-pt))
|
||||
(setq loc-pt (list (car loc-pt) (cadr loc-pt) 0.0)))
|
||||
(setq rot (cond ((cdr (assoc 50 sub-ed))) (0.0)))
|
||||
(setq extrusion (cond ((cdr (assoc 210 sub-ed))) ('(0.0 0.0 1.0))))
|
||||
(setq sx (cond ((cdr (assoc 41 sub-ed))) (1.0)))
|
||||
(setq sy (cond ((cdr (assoc 42 sub-ed))) (1.0)))
|
||||
(setq sz (cond ((cdr (assoc 43 sub-ed))) (1.0)))
|
||||
(setq lx (* bsx (car loc-pt))
|
||||
ly (* bsy (cadr loc-pt))
|
||||
lz (* bsz (cond ((caddr loc-pt)) (0.0))))
|
||||
(setq wx (+ (car basis-pt) (- (* lx c) (* ly si)))
|
||||
wy (+ (cadr basis-pt) (+ (* lx si) (* ly c)))
|
||||
wz (+ (caddr basis-pt) lz))
|
||||
;; Gruppe-10 ist OCS-lokal (relativ zu diesem Sub-INSERTs EIGENER
|
||||
;; Extrusion) - erst in echte lokale Koordinaten der aktuell
|
||||
;; durchsuchten Blockdefinition umrechnen, dann skalieren, dann
|
||||
;; mit der Eltern-Matrix in Weltkoordinaten drehen/verschieben.
|
||||
(setq ocs-mat (mat3-ocs-matrix extrusion))
|
||||
(setq loc-pt-real (mat3-mul-vec3 ocs-mat loc-pt))
|
||||
(setq scaled-pt (list (* bsx (car loc-pt-real))
|
||||
(* bsy (cadr loc-pt-real))
|
||||
(* bsz (caddr loc-pt-real))))
|
||||
(setq rot-pt (mat3-mul-vec3 basis-R scaled-pt))
|
||||
(setq world-pt (list (+ (car basis-pt) (car rot-pt))
|
||||
(+ (cadr basis-pt) (cadr rot-pt))
|
||||
(+ (caddr basis-pt) (caddr rot-pt))))
|
||||
;; Volle 3D-Orientierung dieses Sub-INSERTs in Weltkoordinaten.
|
||||
(setq R-local (mat3-from-normal-rotation extrusion rot))
|
||||
(setq R-world (mat3-mul-mat3 basis-R R-local))
|
||||
(if (wcmatch sub-bname pattern)
|
||||
(setq result (cons (list sub-ent (list wx wy wz) (+ basis-rot rot)
|
||||
(setq result (cons (list sub-ent world-pt R-world
|
||||
(* bsx sx) (* bsy sy) (* bsz sz))
|
||||
result))
|
||||
(setq result (append result
|
||||
(ssg-collect-nested-inserts-rel sub-bname pattern
|
||||
(list wx wy wz) (+ basis-rot rot)
|
||||
world-pt R-world
|
||||
(* bsx sx) (* bsy sy) (* bsz sz))))
|
||||
)
|
||||
)
|
||||
|
||||
+9
-36
@@ -119,42 +119,15 @@
|
||||
;; ============================================================
|
||||
;; TEIL 4b: KS-FRAME MATHEMATIK
|
||||
;; ============================================================
|
||||
|
||||
;; Vektorkreuzprodukt a x b
|
||||
(defun vec3-cross (a b)
|
||||
(list (- (* (cadr a)(caddr b)) (* (caddr a)(cadr b)))
|
||||
(- (* (caddr a)(car b)) (* (car a)(caddr b)))
|
||||
(- (* (car a)(cadr b)) (* (cadr a)(car b)))))
|
||||
|
||||
;; Vektor auf Einheitslaenge normieren
|
||||
(defun vec3-normalize (v / len)
|
||||
(setq len (vec-length v))
|
||||
(if (> len 1e-10)
|
||||
(list (/ (car v) len) (/ (cadr v) len) (/ (caddr v) len))
|
||||
'(1.0 0.0 0.0)))
|
||||
|
||||
;; 3x3-Rotationsmatrix (Zeilenliste) mal 3D-Vektor
|
||||
(defun mat3-mul-vec3 (R v / r0 r1 r2)
|
||||
(setq r0 (car R) r1 (cadr R) r2 (caddr R))
|
||||
(list (+ (* (car r0)(car v)) (* (cadr r0)(cadr v)) (* (caddr r0)(caddr v)))
|
||||
(+ (* (car r1)(car v)) (* (cadr r1)(cadr v)) (* (caddr r1)(caddr v)))
|
||||
(+ (* (car r2)(car v)) (* (cadr r2)(cadr v)) (* (caddr r2)(caddr v)))))
|
||||
|
||||
;; Rotationsmatrix R sodass: R*xe=xt, R*ye=yt, R*ze=zt
|
||||
;; (xt yt zt) = Ziel-Achsen; (xe ye ze) = Quell-Achsen (je normierte Einheitsvektoren)
|
||||
;; Formel: R = M_target * M_source^T
|
||||
;; R[i][j] = xt[i]*xe[j] + yt[i]*ye[j] + zt[i]*ze[j]
|
||||
(defun mat3-from-frames (xt yt zt xe ye ze)
|
||||
(list
|
||||
(list (+ (* (car xt)(car xe)) (* (car yt)(car ye)) (* (car zt)(car ze)))
|
||||
(+ (* (car xt)(cadr xe)) (* (car yt)(cadr ye)) (* (car zt)(cadr ze)))
|
||||
(+ (* (car xt)(caddr xe)) (* (car yt)(caddr ye)) (* (car zt)(caddr ze))))
|
||||
(list (+ (* (cadr xt)(car xe)) (* (cadr yt)(car ye)) (* (cadr zt)(car ze)))
|
||||
(+ (* (cadr xt)(cadr xe)) (* (cadr yt)(cadr ye)) (* (cadr zt)(cadr ze)))
|
||||
(+ (* (cadr xt)(caddr xe)) (* (cadr yt)(caddr ye)) (* (cadr zt)(caddr ze))))
|
||||
(list (+ (* (caddr xt)(car xe)) (* (caddr yt)(car ye)) (* (caddr zt)(car ze)))
|
||||
(+ (* (caddr xt)(cadr xe)) (* (caddr yt)(cadr ye)) (* (caddr zt)(cadr ze)))
|
||||
(+ (* (caddr xt)(caddr xe)) (* (caddr yt)(caddr ye)) (* (caddr zt)(caddr ze))))))
|
||||
;; vec3-cross/vec3-normalize/mat3-mul-vec3/mat3-from-frames (und die
|
||||
;; OCS-/Extrusions-Helfer mat3-mul-mat3/mat3-ocs-basis/mat3-ocs-matrix/
|
||||
;; mat3-rz/mat3-from-normal-rotation) sitzen in ssg_core.lsp, nicht hier:
|
||||
;; ssg-collect-nested-inserts-rel (Export-Zuordnung verpackter Separatoren)
|
||||
;; braucht sie ebenfalls und ist ein CORE-Modul, das IMMER vor vf_core.lsp
|
||||
;; geladen ist - vf_core.lsp selbst ist nur ein Feature-Modul (nicht jede
|
||||
;; Zeichnung laedt VarioFoerderer). Damit beide Seiten dieselbe, einzige
|
||||
;; Definition nutzen, wohnen die allgemeinen Vektor-/Matrix-Helfer im immer
|
||||
;; geladenen Core (wie ssg-rot-matrix-zy schon dort wohnt) statt hier.
|
||||
|
||||
;; Normierter KS-Rahmen aus rohen KS-Daten (origin x-end y-end z-end)
|
||||
;; Eingabe: Teilliste aus extract-ks-from-block-raw, z.B. (cadr (assoc "KS_EIN" ks-data))
|
||||
|
||||
Reference in New Issue
Block a user