| |  | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte | | |  | PNY präsentiert die PRO Elite™ High Endurance microSD-Flash-Speicherkarten für Videoüberwachung und kontinuierliche Aufzeichnung, eine Pressemitteilung
|
Autor
|
Thema: Objeke vergleichen (786 mal gelesen)
|
Benny4 Mitglied Softwareentwickler
 
 Beiträge: 178 Registriert: 16.02.2006 AutoCAD 2010 ZW-CAD 2012
|
erstellt am: 25. Nov. 2008 14:37 <-- editieren / zitieren --> Unities abgeben:         
Hallo, ich habe eine Funktion geschrieben, die alle ausgewählten Linien miteinander vergleicht. Alle Linien, die zusammenhängen, also den Start- oder Enpunkt gleich haben werden in einer AutoCAD-Gruppe zusammengefasst. Das funktioniert eigentlich auch ohne Probleme. Nur wenn ich da mehrere Objekte habe dauert der ganze Vorgang doch etwas lange. (Bei ca. 2000 Linien an die 50 Sekunden). Und das möchte ich optimieren. Hat jemand von euch noch eine Idee? Anbei mal der Code: Nach der Auswahl der Objekte schreibe ich alle Linien in einen Array mit dem Typ entityList. Wenn eine Linie gefunden wurde wird in groupName der Gruppenname reingeschrieben. Somit konnte ich verhindern, dass bereits durchsuchte Objekte nochmal durchsucht werden, was alles schon ein bisschen beschleunigt hat. Sollte aber noch schneller werden.
Code:
Private Type entityList id As Long entity As AcadLine groupName As String End TypePrivate Sub findNextEntity(entitys() As entityList, index As Long, ByRef myGroup, grpName As String) Dim i As Long Dim myObjects(0 To 0) As Object On Error Resume Next For i = 1 To UBound(entitys) 'If i <> index And StrComp(entitys(i).groupName, "", vbTextCompare) = 0 Then 'If i <> index And entitys(i).groupName = "" Then If entitys(i).groupName = "" Then 'MsgBox "Finde nächstes: " & grpName If (Round(entitys(index).entity.StartPoint(0), prez) = Round(entitys(i).entity.StartPoint(0), prez) And _ Round(entitys(index).entity.StartPoint(1), prez) = Round(entitys(i).entity.StartPoint(1), prez) And _ Round(entitys(index).entity.StartPoint(2), prez) = Round(entitys(i).entity.StartPoint(2), prez)) Or _ (Round(entitys(index).entity.StartPoint(0), prez) = Round(entitys(i).entity.EndPoint(0), prez) And _ Round(entitys(index).entity.StartPoint(1), prez) = Round(entitys(i).entity.EndPoint(1), prez) And _ Round(entitys(index).entity.StartPoint(2), prez) = Round(entitys(i).entity.EndPoint(2), prez)) Or _ (Round(entitys(index).entity.EndPoint(0), prez) = Round(entitys(i).entity.StartPoint(0), prez) And _ Round(entitys(index).entity.EndPoint(1), prez) = Round(entitys(i).entity.StartPoint(1), prez) And _ Round(entitys(index).entity.EndPoint(2), prez) = Round(entitys(i).entity.StartPoint(2), prez)) Or _ (Round(entitys(index).entity.EndPoint(0), prez) = Round(entitys(i).entity.EndPoint(0), prez) And _ Round(entitys(index).entity.EndPoint(1), prez) = Round(entitys(i).entity.EndPoint(1), prez) And _ Round(entitys(index).entity.EndPoint(2), prez) = Round(entitys(i).entity.EndPoint(2), prez)) Then Set myObjects(0) = entitys(i).entity entitys(i).groupName = grpName myGroup.AppendItems myObjects findNextEntity entitys, i, myGroup, grpName End If End If Next End Sub
------------------ Grüsse Benny Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 25. Nov. 2008 14:47 <-- editieren / zitieren -->
Hi, wenn Du schon mit gerundeten Koordinaten arbeitest, dann mach die Berechnung der Rundung beim Einlesen der Linien und speichere den gerundeten Wert in Deinem ObjektTyp 'entityList' gleich mit ab. In diesem Vorgang machst Du Dir 2 Punktdefinitionen, in dem Du auch gleich festlegst, daß immer der 'linkere' Punkt, und wenn die Linie senkrecht ist, der untere Punkt als PKT1 abgespeichert wird und der andere als PKT2, damit brauchst Du nicht mehr Start<<>>Start | | Start<<>>End | | End<<>>Start | | End<<>>End vergleichen, sondern nur mehr PKT1<<>>PKT1 | | PKT2<<>>PKT2 Last but not least: vergleiche nicht alle Werte, wenn ein Kriterium schon nicht erfüllt ist, brauchst Du zweites nicht mehr prüfen (Deine Routine hat zuviele 'OR' drin) - alfred - [EDIT]Deine Rekursive Arbeitsweise fährt hier falsch!! Wenn ich das richtig lese, arbeitest Du Dich 2000^(2000-1) mal durch (bei 2000 Elementen)[/EDIT] [Diese Nachricht wurde von a.n. am 25. Nov. 2008 editiert.] |
Benny4 Mitglied Softwareentwickler
 
 Beiträge: 178 Registriert: 16.02.2006 AutoCAD 2010 ZW-CAD 2012
|
erstellt am: 25. Nov. 2008 15:27 <-- editieren / zitieren --> Unities abgeben:         
|
Ex-Mitglied
|
erstellt am: 25. Nov. 2008 15:30 <-- editieren / zitieren -->
Hi, beachte bitte auch das nachträglich (gerade eben) editierte, die falsch angelegte Rekursion!! - alfred - |
Benny4 Mitglied Softwareentwickler
 
 Beiträge: 178 Registriert: 16.02.2006 AutoCAD 2010 ZW-CAD 2012
|
erstellt am: 25. Nov. 2008 15:39 <-- editieren / zitieren --> Unities abgeben:         
Hi, das mit der rekursiven Funktion verstehe ich nicht ganz, was da falsch ist. Mein Gedankengang war der: Wenn ich eine Linie finde, die den selben Start- oder Enpunkt hat wie die vorherige, dann suche ich in allen Objekten nach neuen Linien, die an die neu gefundene angrenzt. Weil es kann ja durchaus sein, dass die neu gefunden Linie angrenzende Linien hat die an vorheriger Stelle in meiner Liste gespeichert wurden. ------------------ Grüsse Benny Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 25. Nov. 2008 16:54 <-- editieren / zitieren -->
Hi, wenn ich es kurz formulieren soll, dann folgende Erklärung: Wenn Du schon Element 1 mit Element 9 verglichen hast, dann brauchst Du, wenn Du beim Element 9 bist, dieses nicht nochmals mit 1 vergleichen - alfred - |
fuchsi Mitglied Programmierer c#.net Datawarehouse
   
 Beiträge: 1201 Registriert: 14.10.2003 AutoCad Version 2012 deu/enu <P>Windows 7 64bit
|
erstellt am: 26. Nov. 2008 12:46 <-- editieren / zitieren --> Unities abgeben:          Nur für Benny4
ich würde das problem anders angehen. Zuerst einen Auswahlsatz über alle Linien (nennen wir ihn MasterAusdwahlsatz). Hiervon die erste Linie nehmen. Dann einen Auswahlsatz erstellen von allen Linien in der zeichnung, wo entweder der Startpunkt mit dem Start oder Endpunkt meiner Linie (und bzw. umgekehrt). Alle diese gefundenen Linien aus dem MasterAuswahlsatz entfernen. Jetzt für alle dies gefunden Linien wiederum rekursiv angrenzende Linien suchen, bis jede dieser Suchen ins Lehre läuft. Jetzt nimmt man wiederum die erste Linie aus dem MasterAuswahlsatz (die gefundenen Linien wurden ja aus diesem entfernt) und wiederholt dieses Spielchen, bis auch der Masterauswahlsatz leer ist. Ich glaube, dass ein Selectionset auf die Zeichnungsdatenbank wesentlich schneller ist, als mathematische Vergleiche von hunderten von Endpunkten. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 26. Nov. 2008 13:26 <-- editieren / zitieren -->
Sorry no! Ich widerspreche ungern, aber in diesem Fall muss ich die 'Regel der Ausnahme' in Anspruch nehmen (bitte nicht böse verstehen, ich bin nicht so ). a) SelectionSets sind alles andere als schnell b) zum Verwalten von Listen (Hinzufügen und Entfernen von Items) ist SelectionSet IMHO die langsamste Version c) Wenn ich ein SelectionSet erstelle, welches mit Option Window oder Crossing arbeitet, dann geht das nicht, wenn die Elemente nicht am Bildschirm sichtbar sind, Fehler sind auch vorprogrammiert für alle Elemente, die zwar sichtbar, aber weit weg gezoomt sind (kleiner 1 Pixel). Damit muss für jede SelectionSet-Bildung zum entsprechenden Ausschnitt hingezoomt werden (was aber z.B. wenn die Anwendung auch in einem Ansichtsfenster laufen soll, das aber gesperrt ist, nicht geht). Das Zoomen einer grösseren Zeichnung zu jedem Endpunkt jeder Line kann nicht schnell sein. - alfred -
[Diese Nachricht wurde von a.n. am 26. Nov. 2008 editiert.] |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
 |