Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de (alle Foren)
  Lisp
  versetzen von Linienkontur

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
  
Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte
Autor Thema:  versetzen von Linienkontur (758 mal gelesen)
floppy
Mitglied


Sehen Sie sich das Profil von floppy an!   Senden Sie eine Private Message an floppy  Schreiben Sie einen Gästebucheintrag für floppy

Beiträge: 7
Registriert: 26.09.2005

erstellt am: 03. Okt. 2005 19:21    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hi allseits!

Ich möchte ein kleines Programm erstellen, dass zusammenhängende Linien versetzt (jeweils um einen bestimmten Offset).
Das Versetzen in LISP und das Verbinden der Linien mit INTERS ist für mich kein Problem. Es kann aber vorkommen, dass bei der versetzten Kontur Linien wegfallen.
Ich muss ausserdem beim Verbinden von einer Startlinie ausgehen, wenn diese Linie aber eigentlich wegfallen würde, dann hab ich ein Problem.
Gibts hier eine Methode die Linien, die weg müssen zu ermitteln?

Danke!

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

andi2050
Mitglied



Sehen Sie sich das Profil von andi2050 an!   Senden Sie eine Private Message an andi2050  Schreiben Sie einen Gästebucheintrag für andi2050

Beiträge: 107
Registriert: 11.03.2003

erstellt am: 03. Okt. 2005 22:02    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für floppy 10 Unities + Antwort hilfreich


Line-Offset.zip

 
Hi floppy !

Die einfachste Lösung ist meiner Meinung nach, die Linien zu einer Polylinie verbinden und dann den Polygonzug mir '_OFFSET' oder '(vla-offset ...) versetzen. Könnte für Deine Zwecke vielleicht ausreichend sein. Jedoch ist der Versetzbefehl von ACAD bei komplexen Konturen nicht ganz korrekt. (Bei AC2002 war es jedenfalls so)

Den Offset-Befehl selbst nachprogrammieren ist eine haarige Angelegenheit.
Hab mich auch schon vor längerer Zeit damit beschäftigt. Jedoch mit geschlossenen Polylinien (Linien und Bögen).

Mein erster Ansatz war folgendermaßen :
- alle Segemente verstezten
- ALLE Segmente miteinander verschneiden und brechen
- ALLE errechneten Linienbruchstücke prüfen:
  Linienbruchstücke, bei denen ein oder beide Endpunkte nicht auf der richtigen Offsetseite liegen, oder einen geringeren/größeren Abstand zur Originalkontur als der Offset haben, entfernen.
- Die restlichen Linien entsprechen der Offsetkontur
 
-> siehe Anhang

Funktioniert zwar prima, aber leider ist der Algorithmus bei komplexen Konturen sehr rechen/zeitaufwändig und bei Bögen nicht 100%ig zuverlässig.

Eine weitere Lösung wäre mit Hilfe des Voronoi-Diagramms möglich.
Auf folgender Seite sind einige Abbildungen von Voronoidiagrammen zu sehen: http://www.cosy.sbg.ac.at/~held/projects/vroni/vroni.html

Grüße

Andi


[Diese Nachricht wurde von andi2050 am 03. Okt. 2005 editiert.]

[Diese Nachricht wurde von andi2050 am 03. Okt. 2005 editiert.]

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

floppy
Mitglied


Sehen Sie sich das Profil von floppy an!   Senden Sie eine Private Message an floppy  Schreiben Sie einen Gästebucheintrag für floppy

Beiträge: 7
Registriert: 26.09.2005

erstellt am: 04. Okt. 2005 21:17    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Andi!

Danke für deinen Lösungsansatz.

Ich hätte dazu noch ein paar Fragen:
Wie bestimmt man, ob ein Bruchstück auf der richtigen oder falschen Seite liegt?
Das mit dem Bruchstückabstand zu Originalkontur hab ich ehrlich gesagt auch nich so ganz kapiert. Kann es sein, dass diese Prüfung nur funktioniert, wenn alle Linien den selben Versetzabstand haben. Ich möchte nämlich jede Linie um jeweils einen individuellen Abstand versetzen - was ja leider der Autocad Versetzbefehl nicht kann.

Mein Lösungsansatz wäre folgender:
1. Alle Linien in die richtige Reihenfolge bringen (z.B. im Uhrzeigersinn)
2. Alle Linien versetzen
3. Alle Linie wieder in der urspr. Reihenfolge verbinden (schneiden)
4. Von der 1. versetzten Linie ausgehen und alle Linien prüfen, ob sie mit dieser schneiden (nicht unendlich). Die Linie, die die Startlinie am kürzesten schneidet "gewinnt", ev. dazwischen liegende Linien fallen unter den Tisch, usw. mit den nächsten Linien.

Das Problem hierbei besteht jedoch darin: wenn die Startlinie eigentlich wegfallen würde, dann stimmt die Kontur nicht. Ich muss also noch einen Weg finden, zu bestimmen, ob die Startlinie auch in der resultierenden Kontur vorhanden ist.
Puhh!

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

andi2050
Mitglied



Sehen Sie sich das Profil von andi2050 an!   Senden Sie eine Private Message an andi2050  Schreiben Sie einen Gästebucheintrag für andi2050

Beiträge: 107
Registriert: 11.03.2003

erstellt am: 08. Okt. 2005 22:06    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für floppy 10 Unities + Antwort hilfreich


OffsetGleich.JPG


OffsetUngleich.JPG


OffsetErsteLine.JPG

 
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

floppy
Mitglied


Sehen Sie sich das Profil von floppy an!   Senden Sie eine Private Message an floppy  Schreiben Sie einen Gästebucheintrag für floppy

Beiträge: 7
Registriert: 26.09.2005

erstellt am: 12. Okt. 2005 21:06    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

Hallo Andi!

Also das Ganze soll ein kleines Programm werden, um Mauern zu konstruieren.
Die Idee dahinter ist, dass der Benutzer die (Mauer)Linienkontur zeichnet (Innenkanten der Mauer), dann das Programm startet und die Mauerlinien auswählt.
Dann muss man bei einer offenen Kontur die erste Mauerlinie wählen bzw. bei einer geschlossen Kontur die erste Mauerlinie nähe des Startpunktes. Der Konturverlauf wird im Uhrzeigersinn angenommen.
Das Programm ordnet die Linien dann in der richtigen Reihenfolge in einer Liste an.
Es werden auch bereits alle Linien aussortiert, deren Winkel nicht gleich wie in der Originalkontur ist und die mit der Originalkontur schneiden. Wobei laut meinen Tests die Startlinie immer noch dabei sein kann.
Im Dialogfenster werden dann in einem Listenfeld die gewählten Linien angezeigt un der Benutzer kann jeder Linie eine Dicke und auch Mauerhöhe zuweisen. Soweit ist das Programm fertig.
Dann sollen die Linien versetzt werden und jedes Mauersegment extrudiert werden.

Es kann sich also um offene oder geschlossene Linienzüge handeln.

Zu Punkt 4: Ich gehe davon aus, dass die Linie, deren Schnittpunkt die aktuelle Linie am meisten verkürzt die "Gute" Linie ist und alle anderen ev. schneidenden Linien "Böse" sind und aus der Kontur fallen - wobei - wie gesagt - das nur stimmt wenn die Startlinie in der Kontur verbleibt.

Jedenfalls vielen Dank für Deine Mühe.
Ich werde die beigefügten Lispprogramme mal analysieren.

Sollte ich zu keiner perfekten Lösung kommen, muss ich halt mit einer halbwegs akkuraten Lösung auskommen ;-)

Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP

Anzeige.:

Anzeige: (Infos zum Werbeplatz >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2023 CAD.de | Impressum | Datenschutz