AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Polygon.Inflate

Ein Thema von Bjoerk · begonnen am 7. Jul 2014 · letzter Beitrag vom 8. Jul 2014
Antwort Antwort
Jens01

Registriert seit: 14. Apr 2009
670 Beiträge
 
#1

AW: Polygon.Inflate

  Alt 7. Jul 2014, 11:17
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?
Achtung: Bin kein Informatiker sondern komme vom Bau.

Geändert von Jens01 ( 7. Jul 2014 um 11:30 Uhr)
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
674 Beiträge
 
Delphi 12 Athens
 
#2

AW: Polygon.Inflate

  Alt 7. Jul 2014, 11:53
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.

Geändert von bcvs ( 7. Jul 2014 um 11:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.545 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Polygon.Inflate

  Alt 7. Jul 2014, 12:38
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
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
670 Beiträge
 
#4

AW: Polygon.Inflate

  Alt 7. Jul 2014, 12:49
Sowas?
Achtung: Bin kein Informatiker sondern komme vom Bau.

Geändert von Jens01 ( 7. Jul 2014 um 12:51 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Polygon.Inflate

  Alt 7. Jul 2014, 12:59
Leider nicht. Das ist wohl das:
Delphi-Quellcode:
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;
Bin noch am rumprobieren. Melde mich nochmal.
  Mit Zitat antworten Zitat
Benutzerbild von ibp
ibp

Registriert seit: 31. Mär 2004
Ort: Frankfurt am Main
1.511 Beiträge
 
Delphi 7 Architect
 
#6

AW: Polygon.Inflate

  Alt 8. Jul 2014, 07:34
also die zentrische Streckung ist eigentlich genau das was du brauchst nur leicht abgewandelt.

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...
Angehängte Grafiken
Dateityp: jpg polygon.jpg (25,5 KB, 11x aufgerufen)

Geändert von ibp ( 8. Jul 2014 um 07:56 Uhr) Grund: Ergänzung
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#7

AW: Polygon.Inflate

  Alt 8. Jul 2014, 08:12
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?
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.051 Beiträge
 
Delphi 12 Athens
 
#8

AW: Polygon.Inflate

  Alt 8. Jul 2014, 09:01
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.
So wird das allerdings schon klarer. Die vier Margins sind dann die jeweilige Mindestdicke der Betondeckung links, rechts, oben und unten. Aber wie wird die Dicke der Betondeckung bei einer Schräge bestimmt?
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
674 Beiträge
 
Delphi 12 Athens
 
#9

AW: Polygon.Inflate

  Alt 8. Jul 2014, 09:15
Das war mir die ganze Zeit schon klar.

Das muss man anhand der Winkels der schrägen Kante bestimmen. Im einfachsten Fall: < 45° Betondeckung für oben bzw unten, >45°: Betondeckung für seitlich (rechts und links müssten eigentlich immer gleich sein). Es kann aber auch sein, dass die Grenze woanders liegen müsste. Das kann ich gerade nicht beurteilen, dazu müsste man sich tiefer in die technischen Gegebenheiten einarbeiten.

Das Problem des OP ist allerdings: wie unterscheide ich bei einer horizontalen Kante, ob die oben oder unten ist. Eine Lösungsmöglichkeit hat er selbst geliefert, einen anderen Vorschlag habe ich gemacht.

Das Grundprinzip der Parallelverschiebung der Kanten ist auch gelöst (#33). Also sollte momentan alles gut sein.

Geändert von bcvs ( 8. Jul 2014 um 10:24 Uhr)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Polygon.Inflate

  Alt 8. Jul 2014, 12:17
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.
So wird das allerdings schon klarer. Die vier Margins sind dann die jeweilige Mindestdicke der Betondeckung links, rechts, oben und unten. Aber wie wird die Dicke der Betondeckung bei einer Schräge bestimmt?
Betondeckungen verstehen sich immer parallel zur Polygonline.

Vielleicht hierzu meine Methode CornerStyle. Die liefert das "Align" eines Knotens.
Zum Beispiel bekommt ein Polygonknoten CornerStyle = csTopLeft die Margens Top und Left.

Und in #33 ist noch ein Indexfehler drin. Punkt 0 wird nach 1 gespeichert, 1 nach 2 usw..

Delphi-Quellcode:
procedure TPolygon.Inflate(Value: double);
var
  I, J: integer;
  C: TFloatPoint;
  Line: TFloatLine;
  Lines: TFloatLines;
begin
  if FCount > 2 then
  begin
    Lines := TFloatLines.Create;
    try
      if Area < 0 then
        Value := -Value;
      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;
      C.Clear;
      Add(C);
      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;
      ExChange(0, FCount - 1);
      Del(FCount - 1);
    finally
      Lines.Free;
    end;
  end;
end;

function TPolygon.CornerStyle(const Index: integer): TCornerStyle;
var
  Temp: TPolygon;
  dX, dY: double;
begin
  if (FCount > 2) and (Index > -1) and (Index < FCount) then
  begin
    Temp := TPolygon.Create;
    try
      Temp.Assign(Self);
      Temp.Inflate(1);
      dX := Temp[Index].X - FItems[Index].X;
      dY := Temp[Index].Y - FItems[Index].Y;
      if (dX < 0) and (dY > 0) then
        Result := csTopRight
      else
        if (dX < 0) and (dY < 0) then
          Result := csBottomRight
        else
          if (dX > 0) and (dY < 0) then
            Result := csBottomLeft
          else
            Result := csTopLeft; // (dX > 0) and (dY > 0)
      // ShowMessage(Format('%d: (%2.f %2.f) %2.f (%2.f %2.f) %2.f = %d',
      // [Index, FItems[Index].X, FItems[Index].Y, dX,
      // Temp[Index].X, Temp[Index].Y, dY, Integer(Result)]));
    finally
      Temp.Free;
    end;
  end;
end;
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz