| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
| |
| PNY wird von NVIDIA zum Händler des Jahres gewählt – zum dritten Mal in Folge, eine Pressemitteilung
|
Autor
|
Thema: Peinliche Frage - Transformation ? (1617 / mal gelesen)
|
cadplayer Ehrenmitglied CADniker
Beiträge: 1833 Registriert: 28.04.2009
|
erstellt am: 04. Jul. 2017 20:20 <-- editieren / zitieren --> Unities abgeben:
Hallo! Ich bin auf ein interessantes Themas gestossen, wobei bei mir gewisse Grundkenntnisse in der höheren Mathematik fehlen (nicht Thema für Realschüler). Thema Vektoren und Matrizenberechnung. Kurz gesagt ich möchte bezüglich einer gewählten Polylinie die naheliegenden Kreismittelpunkte lotrecht berechnen lassen und dann die Kreise entsprechend des ermittelten Lotpunktes verschieben. 1) Frage: Was benötige ich dazu ? - Vektor ... entspricht einer gedachten Linie vom Kreismittelpunkt zum Lotpunkt Code: Vector3d vec = polyInters - circleCenter;
2) Frage: Transformationsberechnung mittels Matrix wie ? - ent2.TransformBy(Matrix3d... Mein bisheriger Ansatz
Code: private void UpdateLinkedEntities(ObjectId from) { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; ObjectIdCollection linked = m_linkManager.GetLinkedObjects(from); Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { try { Point3d polyInters; Point3d circleCenter; double firstRadius; double secondRadius; Entity entPoly = (Entity)tr.GetObject(from, OpenMode.ForRead); if (entPoly.ObjectId.IsValid) { foreach (ObjectId to in linked) { Entity ent2 = (Entity)tr.GetObject(to, OpenMode.ForRead); if (GetCenterAndRadius(ent2, out circleCenter, out secondRadius)) { Polyline poly = (Polyline)tr.GetObject(entPoly.ObjectId, OpenMode.ForRead); polyInters = poly.GetClosestPointTo(circleCenter, true); Vector3d vec = polyInters - circleCenter; if (!vec.IsZeroLength()) { // Only move the linked circle if it's not // already near enough //double apart = vec.Length - (firstRadius + secondRadius); //if (apart < 0.0) // apart = -apart; double apart = vec.Length - ; if (apart > 0.00001) { ent2.UpgradeOpen(); ent2.TransformBy(Matrix3d.Displacement(vec.GetNormal() * apart)); } }
Anmerkung: entPoly: entspricht der Polylinie ent2: entspricht dem Kreis polyInters: erechnete Lotpunkt vom Kreismittelpunkt zur Polylinie Sorry Mathe ist nicht unbedingt meine Stärke, vielleicht kann sich einer die Mühe machen, mir ein wenig Nachhilfe zu geben. Danke schonmal für eure Mühe!
------------------ Gruss Dirk Blog
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2799 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2023 Plateia, Canalis Visual Basic
|
erstellt am: 04. Jul. 2017 22:38 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Hallo Dirk, Keine Ahnung warum Du hierfür auf die höhere Mathematik zurückgreifen möchtest. Du brauchst doch nur die kürzeste Entfernung des Kreismittelpunktes auf die einzelnen Polyliniensegmente suchen. D.h. Du hast das Lot auf eine Linie. Einen VBA Code zur Berechnung hatte ich mal hier gepostet Das ganze in eine Funktion gepackt und Du hast den Verschiebevektor (Lotfußpunkt-Mittelpunkt) Grüße Klaus Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadplayer Ehrenmitglied CADniker
Beiträge: 1833 Registriert: 28.04.2009
|
erstellt am: 05. Jul. 2017 08:41 <-- editieren / zitieren --> Unities abgeben:
Danke Klas! Ich glaube du hast nicht richtig verstanden, worauf ich aus bin. Den Lotpunkt habe ich ja bereits mit poly.GetClosestPointTo(circleCenter, true); ermittelt. Dein Kod ermittelt mittels Geradenschnitt den Lotpunkt, was ich nicht unbedingt benötige... Mein Problem besteht hauptsächlich in der Zeile Code: ent2.TransformBy(Matrix3d....);
Hier soll nämlich das CircleEntity auf den Lotpunktverschoben werden, dazu muss man eine Matrize ermitten, die die Methode TransformBy benötigt. Die Matrize wiederum Code: Matrix3d.Displacement(vec.GetNormal() * apart)
benötigt die Parameter für den Verktor und so vermute ich den Streckenwert (Länge der Lotlinie). Da mir Vektor und Matrize zwei völlig unbekannte Begriffe sind, ist die Frage, wie man damit hantiert (vielleicht gibt es ein kleines 1x1 dafür) ------------------ Gruss Dirk Blog
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Brischke Moderator CAD on demand GmbH
Beiträge: 4187 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools
|
erstellt am: 05. Jul. 2017 09:12 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Hallo Dirk, Code:
Matrix3d.Displacement(VECTOR)
Ein Vector besitzt die Eigenschaften X Y Z - also genau wie ein Punkt, nur dass diese Werte als Delta-X Delta-Y Delta-Z zu verstehen sind. Die Matrizenrechnung benötigst du in Acad nur selten, weil mit den Matrix3d.* Funktionen alle Funktionen zum Bilden der Matrix vorhanden sind. Das heißt nun für deine obige Funktion: Es wird die Matrix berechnet, die die Verschiebung um die Werte Delta-X Delta-Y Delta-Z (Werte aus dem übergebenen Vector) definiert. Die TransformBy-Methode der Entities führt dann eben genau die Transformation durch, die in der Matrix definiert ist. Soweit klar? Allgemeine Unterlagen zu Vektoren und Transformationsmatrizen findest du sicher im Netz. Grüße! Holger ------------------ Holger Brischke CAD on demand GmbH Individuelle Lösungen von Heute auf Morgen.
defun-tools Das Download-Portal für AutoCAD-Zusatzprogramme!
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadplayer Ehrenmitglied CADniker
Beiträge: 1833 Registriert: 28.04.2009
|
erstellt am: 05. Jul. 2017 10:08 <-- editieren / zitieren --> Unities abgeben:
|
cadplayer Ehrenmitglied CADniker
Beiträge: 1833 Registriert: 28.04.2009 Windows 10 64bit system Autocad Civil3d 2020 ENGLISH Visual Studio 2019 OpenDCL.Runtime.9<P>
|
erstellt am: 07. Jul. 2017 08:23 <-- editieren / zitieren --> Unities abgeben:
Hier eine Lösung wie man beispielsweise einen Kreis mittels Transformation verschieben kann. Da hatte ich wiedermal einen Knoten im Kopf. Da es in meiner Funktion nicht richtig ging, musste ich es mir so herleiten. Danke nochmals Holger! [CODE][ using System; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; [assembly: CommandClass( typeof( LaneHeights_LinkingCircles.Move ) ) ] namespace LaneHeights_LinkingCircles { public class Move { [CommandMethod("MoveCircle")] public static void MoveObject() { // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor ed = acDoc.Editor; // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { PromptEntityOptions poCi = new PromptEntityOptions("\nSelect Circle! "); poCi.SetRejectMessage("\nOnly Circle can be selected."); poCi.AddAllowedClass(typeof(Circle), false); PromptEntityResult res = ed.GetEntity(poCi); ObjectId from = res.ObjectId; if (res.Status == PromptStatus.OK) { ObjectId id = res.ObjectId; Circle acCirc = acTrans.GetObject(id, OpenMode.ForWrite) as Circle; PromptPointOptions pos = new PromptPointOptions("\nGet new position!"); // Create a matrix and move the circle using a vector from cCenter to acPt3d PromptPointResult pr = ed.GetPoint(pos); Point3d acPt3d = pr.Value; Point3d cCenter = acCirc.Center; Vector3d acVec3d = cCenter.GetVectorTo(acPt3d); acCirc.TransformBy(Matrix3d.Displacement(acVec3d)); } // Save the new objects to the database acTrans.Commit(); } } } } /CODE]
------------------ Gruss Dirk Blog
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ingenieur Studio HOLLAUS Mitglied CAD / CAFM / GIS Beratung-Programmierung-Schulung
Beiträge: 1049 Registriert: 06.11.2008 Autocad 2 bis Autocad 2020 (+Map3D, +Civil3D, +Infraworks) RKV .... CAFM+mehr HMap ... Vermessung und Verkehr OoC .... Raumplanung CBox ... Tools für AutoCAD und BricsCAD (kostenfrei)
|
erstellt am: 08. Jul. 2017 17:29 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Zitat: Den Lotpunkt habe ich ja bereits mit poly.GetClosestPointTo(circleCenter, true)
Sorry, aber ich kann mir nicht vorstellen, dass das funktioniert. Siehe Screenshot, die Funktion Polyline.GetClosestPointTo(Point,true) liefert Punkt(A) als Ergebnis. Punkt(B)(C) und (D) wären lotrechte Punkte (lotrecht vom Kreismittelpunkt zur Polyline), aber diese werden aus obiger Funktion nicht returniert. ------------------
www.cars4fun.at Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KlaK Ehrenmitglied V.I.P. h.c. Dipl. Ing. Vermessung, CAD- und Netz-Admin
Beiträge: 2799 Registriert: 02.05.2006 AutoCAD LandDesktop R2 bis 2004 Civil 3D 2005 - 2023 Plateia, Canalis Visual Basic
|
erstellt am: 09. Jul. 2017 19:46 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Zitat: Danke Klaus! Ich glaube du hast nicht richtig verstanden, worauf ich aus bin. Den Lotpunkt habe ich ja bereits mit poly.GetClosestPointTo(circleCenter, true); ermittelt. Dein Code ermittelt mittels Geradenschnitt den Lotpunkt, was ich nicht unbedingt benötige...
@cadplayer, ja das habe ich beim nächsten analysieren Deines Codes auch festgestellt. So eine Funktion (getClosestPointTo) habe ich damals auch unter VBA entwickelt, der Lotfußpunkt war da ein Teil davon. Die Verschiebung wäre auch ganz einfach ohne Vektorfunktion zu berechnen gewesen, sind ja nur Verschiebungen auf einer Geraden. Aber Sorry, da habe ich wohl falsch gelesen. VBA bietet da wesentlich weniger Funktionen, vielleicht sollte ich doch mal umsteigen ... @Studio Hollaus: Der Lotfußpunkt ist beim kürzesten Abstand nicht unbedingt gefragt und stellt nur ein Kriterium der Lagefindung dar. Stell Dir vor Du hast eine Polylinie die eine Gewässerachse darstellt aber nicht stetig ist (Knickpunkte statt Ausrundungen wie in Deiner Zeichnung). Jetzt sollen bestimmte Punkte auf dieser Achse stationiert werden ... Die Probleme der Stationierung, alle Punkte zwischen B und C erhalten die Station von A, muß natürlich mit dem AG besprochen werden und evtl. hier eine geringe Verschiebung erfolgen. Gleiches natürlich am Punkt D, der theoretisch von beiden Linien den gleichen Abstand haben kann. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ingenieur Studio HOLLAUS Mitglied CAD / CAFM / GIS Beratung-Programmierung-Schulung
Beiträge: 1049 Registriert: 06.11.2008 Autocad 2 bis Autocad 2020 (+Map3D, +Civil3D, +Infraworks) RKV .... CAFM+mehr HMap ... Vermessung und Verkehr OoC .... Raumplanung CBox ... Tools für AutoCAD und BricsCAD (kostenfrei)
|
erstellt am: 10. Jul. 2017 00:03 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Zitat: Der Lotfußpunkt ist beim kürzesten Abstand nicht unbedingt gefragt
"Lotfußpunkt" oder "Stationierung" sehe ich in der Fragestellung nicht. Ich kann in diesem Thread nur erkennen, dass dieses gefragt war: "ich möchte bezüglich einer gewählten Polylinie die naheliegenden Kreismittelpunkte lotrecht berechnen lassen" Und mein Hinweis bezog sich lediglich darauf, dass die Funktion GetClosestPointTo auch Punkte retournieren kann, die nicht lotrecht auf eine Polyline zeigen.
------------------
www.cars4fun.at Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |