Hi Floppy !
Nur mal zum Grundsätzlichen Verständnis :
Handelt es sich um offene oder geschlossene Linienzüge ? (bei geschlossenen läßt sich des Problem mit der 1.Linie umgehen)
Wie ordnest Du die unterschiedlichen Offsets den Linien zu ?
Wofür ist das Ganze eigentlich gedacht ?
Der Lösungsansatz sieht meiner Meinung nach ganz gut aus.
Wenn ich Punkt 4 ("Gute und Böse" Segmente finden) richtig verstanden habe, gehst Du davon aus, daß sich "Gute" und "Böse" Bereiche von Schnittpunkt zu Schnittpunkt abwechseln.
Wenn die 1.Linie wegfällt fängt die Offsetkontur "Böse" an, ansonsten "Gut".
Ob das immer so ist kann ich nicht 100%ig sagen. Siehe OffsetUngleich.jpg
In meinem Fall habe ich das durch den Abstand der Segmente zur Originalkontur gelöst, geht aber nur bei gleichmäßigem Offset, wie Du vermutet hast. -> siehe OffsetGleich.jpg.
Daß die 1.Linie wegfällt könnetst Du daran erkennen, daß ist die 1.Offsetlinie (vermutlich) gegeläufig zur 1.Originallinie ist. siehe OffsetErsteLine.jpg
Hab ich aber nicht ausführlich getestet, ist nur so eine Vermutung (kommt auch daruf an, wie Du die Offsetkontur berechnest).
Ich habe hier ein paar Funktionen angehängt, mit deren Hilfe man prüfen kann ob ein Punkt links, rechts oder auf einer Kontur liegt (is-pt-right, is-pt-on-obj).
Bei zusammenhängenden Linien müssen diese aber zu einer Polylinie verbunden sein. Funktioniert aber nur zuverlässig mit OFFENEN Polylinien OHNE Bulges (Bögen). Die Funktion "C:TEST" ist nur zum ausprobieren -> Polylinie wählen und dann den Cursor um die Kontur bewegen. Links unten in der Statuszeile wird dann Links oder Rechts angezeigt.
Hier der Code :
;;; -----------------------------------
;;; Nur TESTFUNKTION
;;; in der Statuszeile wird die Position des Cursors
;;; in Bezug zum gewählten Objekt angezeigt.
;;; -----------------------------------
(defun c:test (/ ename givenpt curve-obj)
(setq ename (car (entsel "\nPline wählen:"))
curve-obj (vlax-ename->vla-object ename)
)
(while (/= 3 (car (setq givenpt (grread t))))
(setq givenpt (trans (cadr givenpt) 1 0))
;;; (setq givenpt (vlax-curve-getclosestpointto curve-obj givenpt))
(grtext -2
(cond ((is-pt-on-obj curve-obj givenpt) "Drauf")
((is-pt-right curve-obj givenpt) "Rechts")
(t "Links")
)
)
)
)
;;;*******************************************************************************************
;;;------------------------------
;;; is-pt-on-obj
;;; Argumente: curve-obj - VlaObj von CurveObj
;;; point - Zu prüfender Punkt
;;; Rückgabe: T / nil
;;;------------------------------
(defun is-pt-on-obj (curve-obj point /)
(equal 0.0 (distance point (vlax-curve-getclosestpointto curve-obj point)) 10E-6)
)
;;;------------------------------
;;; is-pt-right - NUR FÜR LINE oder PLINE OHNE BULGES !!!
;;; Argumente: curve-obj - VlaObj von Polyline
;;; point - Zu prüfender Punkt
;;; Rückgabe: T - Punkt liegt rechts der Kontur
;;; nil - Punkt liegt links der Kontur
;;; ACHTUNG: Wenn Punkt genau auf dem Objekt liegt ist die Rückgabe nicht sicher definiert !!!
;;; -> vorher prüfen ob Punkt auf Objekt liegt !!!
;;;------------------------------
(defun is-pt-right (curve-obj point / closestpara closestpnt endpara firstderiv startpara)
(setq startpara (vlax-curve-getstartparam curve-obj)
endpara (vlax-curve-getendparam curve-obj)
closestpnt (vlax-curve-getclosestpointto curve-obj point)
closestpara (vlax-curve-getparamatpoint curve-obj closestpnt)
angle1 (angle '(0.0 0.0) (vlax-curve-getfirstderiv curve-obj closestpara))
)
(cond ;; Wenn Closestpt = Eck
((and (equal closestpara (fix closestpara)) (/= startpara closestpara) (/= endpara closestpara))
(minusp (deltaang angle1 (angle '(0.0 0.0) (vlax-curve-getfirstderiv curve-obj (1- closestpara)))))
)
;; Wenn Closestpt = Mittendrin oder Start/Endpunkt
(t (minusp (deltaang angle1 (angle closestpnt point))))
)
)
;;;-----------------------------
;;; Hilfsfunktion
;;; Winkel differenz -> Ergebnis zwischen -pi und +pi (-180 und 180 Grad)
;;;-----------------------------
(defun deltaang (ang1 ang2 / ang)
(setq ang (- ang2 ang1))
(cond ((equal 0.0 ang 10e-6) 0.0)
((equal pi ang 10e-6) pi )
((> ang pi) (- ang (* pi 2.0)))
((<= ang (- pi)) (+ ang (* pi 2.0)))
(t (eval ang))
)
)
Auch wenn's nicht sehr hilfreich ist, vielleicht bringt's Dich weiter.
Grüße
Andi
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP