![]() |
Polygon.Inflate
Hat jemand eine Idee für eine Polygon.Inflate?
So gehts schonmal nicht :gruebel:
Delphi-Quellcode:
procedure TPolygon.Inflate(const Top, Bottom, Left, Right: double); // positve Werte verkleinern;
var I: integer; dX, dY, vX, vY: double; P: TFloatPoint; Line: TFLoatLine; begin P := Center; for I := 0 to FCount - 1 do begin dX := FItems[I].X - P.X; dY := FItems[I].Y - P.Y; vX := 0; vY := 0; if (dX > 0) and (dY > 0) then begin vX := Right; vY := Bottom; end else if (dX < 0) and (dY > 0) then begin vX := -Left; vY := Bottom; end else if (dX < 0) and (dY < 0) then begin vX := -Left; vY := -Top; end else if (dX > 0) and (dY < 0) then begin vX := Right; vY := -Top; end; FItems[I].X := FItems[I].X + vX; FItems[I].Y := FItems[I].Y + vY; end; end; |
AW: Polygon.Inflate
Also bei mir ist das alles schon etwas zu lange her um es noch im Kopf zu haben, aber trivial ist das sicher nicht- Vielleicht in Dreiecke zerlegen, diese einzeln aufblasen und anschließend konvexe Hülle bestimmen? Oder hast du bestimmte Einschränkungen für deine Polygone?
|
AW: Polygon.Inflate
Was soll den überhaupt passieren?
Mir fehlt irgendwie die Beschreibung, was die Methode genau tun soll. |
AW: Polygon.Inflate
Was soll denn dein Inflate machen?
|
AW: Polygon.Inflate
Inflate vergrößert oder verkleinert ein Polygon oder auch ein
![]() |
AW: Polygon.Inflate
Da gibt es mehrere Ansätze. Ich würde spontan folgendes tun:
Für jeden zu verschiebenden Punkt, nehme seine 2 benachbarten Punkte und bilde die Strecke zwischen diesen. Drehe diese um 90°, und verschiebe den Punkt um einen Faktor an dieser "Quasi-Normalen". Dazu sollte die Verschiebung natürlich an einer Kopie erfolgen, sonst beeinflusst man ja die nachfolgenden Berechnungen. Man müsste dann nur ausprobieren, ob man die Normalen normalisiert, oder lieber in ihrer Länge belässt und nur mit dem Inflate-Faktor multipliziert. Ich kann mir für beide Varianten Argumente vorstellen, würde aber naiv erstmal zum Normalisieren tendieren. |
AW: Polygon.Inflate
Im Prinzip wie InflateRect. Es muß für alle Polygone gehen. Allerdings sind die Polygone hier immer geschlossen und math. positiv. Es gibt keine negativen Anteile. Brauch ich für mein Bewehrungsmodul. Da werden vier Betondeckungen (Margins) vorgeben.
Code:
xxxxxxxxxxxxxxxxx
x ............. x x ........ . x xxxxxxxxx . . x x . . x x ....... x xxxxxxxxxxxx |
AW: Polygon.Inflate
Grober Gedanke:
Zentrum festlegen (geht das?, wenn nicht gehts sowieso nicht). Den Vektor (Zentrum-Polygonpunkt) jeweils verlängern. Gruss Jens P.S. Mit einer Triangulation und der Vergrößerung der einzelnen Dreiecke könnte es auch gehen? :) |
AW: Polygon.Inflate
Zitat:
Kannst du eine Regel formulieren, was mit jeder Polygonkante passieren soll? Die Analogie zu InflateRect erschließt sich mir hier noch nicht vollständig oder ist zumindest lückenhaft. Ich kann eigentlich nur dann intuitiv etwas ableiten, wenn man von dem Polygon genau die Punkte und Kanten betrachtet, die auf dem umschließenden Rechteck liegen. |
AW: Polygon.Inflate
Ich würde einfach die Kanten parallel verschieben, und zwar je nach Lage der Kante um Top, Bottom, Left oder Right. Du musst nur eine Regel für die schrägen Kanten festlegen: gilt da die Betondeckung für oben/ unten oder seitlich? (evtl. aghängig von der Neigung der Kante). Dann neue Schnittpunkte bestimmen. Das sind dann die neuen Polygonpunkte.
|
AW: Polygon.Inflate
Aus der hohlen Hand würde mir einfallen: umgebendes Rechteck ermitteln und das prozentuale Verhältnis jedes einzelnen Punktes relativ zur linken oberen Ecke ermitteln. Dann das umgebende Rechteck vergrößern/verkleinern und die neuen Punkt-Positionen anhand des gemerkten Verhältnisses neu berechnen. Das jeweilige Original-Verhältnis sollte man dabei aber im Speicher behalten, sonst wird das nach ein paar Mal vergrößern/verkleinern wahrscheinlich zu ungenau. Vielleicht taugt das aber auch alles nix, so dolle bin ich nicht in Geometrie :stupid:
|
AW: Polygon.Inflate
|
AW: Polygon.Inflate
Zitat:
Delphi-Quellcode:
Bin noch am rumprobieren. Melde mich nochmal.
procedure TPolygon.CenterZoom(const Faktor: double);
var I: integer; P1, P2: TFloatPoint; begin P1 := Center; for I := 0 to FCount - 1 do begin FItems[I].X := FItems[I].X * Faktor; FItems[I].Y := FItems[I].Y * Faktor; end; P2 := Center; for I := 0 to FCount - 1 do begin FItems[I].X := FItems[I].X - (P2.X - P1.X); FItems[I].Y := FItems[I].Y - (P2.Y - P1.Y); end; end; |
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
Zitat:
Kannst du das vielleicht mal aufmalen? Betrachtest du eventuell nur eine bestimmte Klasse von Polygonen? Wie wäre ein Fall wie PolygonForm (außen) = Dreieck mit Spitze oben, PolygonPanel (innen) = Dreieck mit Spitze unten zu behandeln? Wie ich schon sagte, intuitiv kann ich mir das vorstellen, wenn um das Polygon ein umfassendes Rechteck mit den vier Margins gelegt werden soll. Dann kann man aber auch gleich das Rechteck so definieren, daß die Margins zu Null werden. Das entspricht wiederum der Darstellung des Polygons in einem rechteckigen Viewport. Man muss nur festlegen, was mit dem Polygon passieren soll, wenn es nicht in dieses Viewport passt. Soll es skaliert werden? Soll es soweit verändert werden, daß alle Punkte drin liegen? Soll es abgeschnitten werden (Clipping)? |
AW: Polygon.Inflate
Die Grundfrage ist doch die:
Beschreiben deine 4 Margins Kantenverschiebungen senkrecht zu den bisherigen Polygon-Kanten oder senkrecht zu den Kanten eines umhüllenden Rechtecks? Wenn es sich um Betondeckungen handelt, sind die wohl senkrecht zu den Polygonkanten gemeint, sonst macht es ja keinen Sinn. Du willst wahrscheinlich die Vorgaben der DIN, die nur für oben/unten/seitlich angegeben sind, für polygonale Querschnitte umsetzen. Was man da noch braucht, ist bei schrägen Kanten eine Unterscheidung, welches Margin denn nun gilt, Abhängig von der Neigung und der Lage (z.B -45° bis +45°: Margin für oben, +45° bis 135°: Margin für rechts etc.) Um dieses Margin wird die Kante dann parallel verschoben. P.S.: Interessant, dass man hier noch mehr Bau-Menschen findet. Bin auch so einer. |
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
Bloß nicht in Dreiecke zerlegen! Das ist ein weitaus komplizierteres Problem.
Such mal die Unit gr32_polygon, da ist genau so eine ![]() |
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
Achso... dann sucht Bjoerk vielleicht Minkowski-Summen? Die Beschreibung liest sich zumindest so.
|
AW: Polygon.Inflate
Also wenn ich das richtig verstehe, geht es hier um eine Skalierungsmethode, die nicht nur einfach die X/Y achsen der punkte basierend zum Mittelpunkt scaliert, sondern auch entscheiden lässt, ob man auf der X achse nur die Punkte skalieren will, die relativ zum Mittelpunkt im Positiven oder Negativen Teilbereich einer Achse liegen?
In diesem Fall würde ich zuerst den Mittelpunkt und die BB(BoundingBox) berechnen und danach selbige in Quadranten aufteilen. Du hast jetzt 4 Bereiche, die bestimmen von welchen der 4 Parametern ein Punkt beeinflusst wird. Liegt ein Punkt im oberen linken Quadranten wird er beeinflusst von Y+ Achse(nteil?) x- Achse Was Top/Left entspricht. Ein punkt der Direkt auf der X-Achse liegt(Egal ob X+ oder X- Teilbereich) kann nicht von der Y-Achse beeinflusst werden. In diesem Fall zählen nur Left oder Right Werte. Dies scheint z.B. im ersten Eintrag gar nicht berücksichtigt zu werden. Das selbe gilt natürlich auch umgekehrt für die Y-Achse |
AW: Polygon.Inflate
Also ich hab jetzt so ziemlich je Kombination von Skalieren und Normalisieren ausprobiert. Scheiten alle daran daß man nicht weiß in welche Richtung man normaliseren muß. Und wie die Bauleute natürlich sofort gemerkt haben, in Wirklichkeit ist es noch viel komplizierter. Die Margins verstehen sich senkrecht zu Polygonline und können auch unterschiedlich sein, z.B. Untere Bewehrung Decke vs. Unterzug..
|
AW: Polygon.Inflate
Zitat:
Zeichne doch mal ein paar aussagekräftige Beispiele. Ein interessantes Beispiel fände ich z.B. einen (näherungsweisen) Kreis... wie soll das Ergebnis dort aussehen? Da gibt es ja nicht nur links, rechts, oben und unten, sondern ganz viele Zwischenstufen. Was genau passiert mit diesen? |
AW: Polygon.Inflate
Es wäre wirklich hilfreich, wenn du dein Problem (wenn möglich ohne Verwendung von Fachbegriffen) vollständig formulieren könntest. Wenn ich das richtig sehe, ist es doch ein rein geometrisches Problem und dazu sollten einige hier was sagen können, selbst wenn sie nicht vom Bau sind. Obwohl ich selbst auch schon so einiges mit Bauleuten gemacht habe, kann ich aus deinen bisherigen Beschreibungen die eigentliche Zielsetzung nicht herauslesen.
Was ich schon mal hatte (im Kunststofffensterbau), war eine Parallelverschiebung (Offset) eines Polygons, bei dem jede Polygonlinie einen eigenen Offset mitbekommt. Ich weiß aber nicht, ob das hier das erwünschte Ziel ist. |
AW: Polygon.Inflate
Ich probiere es nochmals..
Du hast ein Polygon, das vom Bauteilquerschnitt vorgegeben wird. Es gibt für jede Strecke eine parallele Strecke mit bestimmten Abstand. Ich würde jede einzelne Strecke einfach kopieren und parallel verschieben. Die Polygonpunkte werden über die Schnittpunkte der neuen Strecken/ Geraden ermittelt. Oder? |
AW: Polygon.Inflate
Wenn du mir sagst ob der Abstand pos oder neg ist? z.B. T Querschnitt
|
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
Liste der Anhänge anzeigen (Anzahl: 1)
Dank
![]() Interessantes Problem, werd mir Gedanken darüber machen.. soferns richtig ist. |
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
Zitat:
Da das Polygon ja irgendwie gerichtet ist (z.B. positiv bei Umlaufsinn gegen den Uhrzeigersinn), ist auch jede einzelne Strecke im Polygon gerichtet. Anhand dieser Richtung ermittelt man den gewünschten Offsetwert und macht eine Parallelverschiebung der Linie um diesen Wert. Dann berechnet man die Schnittpunkte der benachbarten Linien und erhält somit die neuen Polygonpunkte. Problematisch wird es allerdings, wenn durch die Parallelverschiebung einzelne Polygonsegmente oder ganze Bereiche wegfallen. Das muss man zum einen erst erkennen und dann auch noch richtig behandeln. |
AW: Polygon.Inflate
Das Allerdings kann hier nicht passieren weil der Bewehrungskorb in den Betonquerschnitt reinpassen muß (sonst wird der Statiker auf der Baustelle vom Bauleiter verprügelt). Allerdings, und das hat Jens auch nicht gelöst, woher weiß ein Punkt daß er unten rechts ist.
Beispiel T: Bezüglich des SchwerpunktsKOO ist P2 oben rechts.
Code:
0*************************1
* * 7********6 3********2 * * * * * * * * * * * * * * * 5*******4 |
AW: Polygon.Inflate
Ich würde nicht von Punkten, sondern von Strecken ausgehen. Denen kann man einen Winkel zuordnen.
Was du immer noch nicht beantwortet hast: Was ist jetzt mit Polygonen, die nicht rechtwinklig sind? Ich geb dir jetzt meinetwegen die Margins (Links: 1, Oben: 2, Rechts: 3, Unten: 4) und eine diagonale Strecke im 45°-Winkel:
Code:
Welchen Abstand hat die denn nun?
/
/ / / / |
AW: Polygon.Inflate
Das hab ich mal wieder nicht verstanden? :oops:
Ich lass es jetzt erst mal so. Der Benutzer kann ja dann mehrere Margins in das Polygon legen. Vermutlich ist es auch gar nicht möglich so wie ich wollte. Bei AutoCad muß man beim Ausrunden ja auch einen Bezugspunkt angeben.
Delphi-Quellcode:
procedure TPolygon.Inflate(const Value: double);
var I, J: integer; C: TFloatPoint; Line: TFloatLine; Lines: TFloatLines; begin Lines := TFloatLines.Create; try for I := 0 to FCount - 1 do begin J := Next(I); Line.P1 := FItems[I]; Line.P2 := FItems[J]; Line.ShiftUV(0, Value); Lines.Add(Line); end; Clear; for I := 0 to Lines.Count - 1 do begin J := Lines.Next(I); if Lines.Item[I].IntersectLines(Lines.Item[J], C) then Add(C); end; finally Lines.Free; end; end; |
AW: Polygon.Inflate
Eventuell ist der
![]() |
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
Zitat:
|
AW: Polygon.Inflate
"Er" weiß jetzt langsam wovon "Wir" reden. Was man zum Beispiel machen könnte wäre zuerst (auf einer Kopie) das 08/15-Inflate von #33 durchführen und dann schauen wohin sich der Punkt bewegt hat. Falls nach rechts dann MarignLeft verwenden, falls nach unten dann MarignTop verwenden usw.. Diese Margins verstehen sich für die Polygonlinien (hier) immer als ShiftV. "Er" weiß jetzt nämlich auch daß eine Normalverschiebung U einer Polygonlinie (hier) nichts bringt weil die durch IntersectLines überschrieben wird.
|
AW: Polygon.Inflate
Es gäbe auch noch die Möglichkeit, anhand der Winkel zu unterscheiden, ob eine Kante unten oder oben ist:
Angenommen, in deinem Beispiel aus #31 hat die Linie 4-5 die Neigung 0°, Wenn man jetzt im Uhrzeigersinn die Winkel addiert, hat die Linie 0-1 180° und 2-3 wieder 0°. Also könnte man sagen: alles was annähernd 180° ist, bekommt die Margin für oben und was annähernd 0° ist, Margin für unten. Ab welcher Neigung es dann in die seitlichen Margins übergeht, musst du selbst entscheiden. |
AW: Polygon.Inflate
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Ich gehe davon aus, dass dein Ausgangspolygon das betonierte Resultat sein soll. Die Bewehrung muss zur Außenseite jeweils ein Mindestmaß an Betondeckung aufweisen. Du brauchst nun die Maße der Bewehrung. Wenn du bei der zentrischen Streckung die Eckpunkte zum Zentrum verschiebst und zwar genau so weit bis der Soll-Abstand (Betondeckung) der Strecken zum Ausgangspolygon erreicht ist. Richtig? Zwei benachbarte Eckpunkte solange nach Z verschieben, bis die Strecke in der Ebenenansicht den gewollten Abstand erreicht hat, dann nächsten Punkt usw... |
AW: Polygon.Inflate
Es könnte aber auch sein, das der Threadersteller die Normale eines Punktes berechnen muss(Was der Durchschnitt der beiden Normalen der beiden abgehenden strecken ist) und die Punkte dahingehend skaliert?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz