Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Wie kann man mit HRGN arbeiten? (https://www.delphipraxis.net/168920-wie-kann-man-mit-hrgn-arbeiten.html)

MechMac666 18. Jun 2012 17:59

Wie kann man mit HRGN arbeiten?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich stehe vor folgendem Problem:
Ich lese eine DXF-Datei ein und erstelle daraus ein einzelnes Polygon, welches die Außenkontur beschreibt.
Dies schreibe ich über CreatePolygonRgn in eine HRGN.
Soweit ich verstanden habe, kann ich innerhalb der HRGN nicht mehr auf lppt(die Punkteliste) zugreifen.

Nun habe ich mittels eines Rechteckes und der Außenkontur eine Region mit CombineRgn erzeugt.
Diese ist im Dateianhang zu sehen.

Gibt es eine Möglichkeit, die in ihre vier Bestandteile zu zerlegen? (die blauen Teile)

Gruß, MechMac666

Bummi 18. Jun 2012 19:18

AW: Wie kann man mit HRGN arbeiten?
 
Wenn Du weißt wo Du es zerlegen willst könntest Du in diesem Beispiel mit vier Regions OR,OL,UR,UL und jeweiligen Combine mit Deiner Region 4 Stück erzeugen.
Wenn Du das Ganze irgendwie automatisieren musst, kannst Du vielleicht folgenden Fetzen brauchen ...
Delphi-Quellcode:
procedure TForm5.Button1Click(Sender: TObject);
type
 RgnRects = array[0..0] of TRect;
 pRgnRect = ^RgnRects;
var
 rgn:hrgn;
 RgnData : pRgnData;
 aSize : DWORD;
 RgnPtr : pRgnRect;
 aRect : TRect;
 i:Integer;
begin
 rgn := CreateEllipticrgn(0,0,200,200);
 aSize := GetRegionData(rgn, 0, nil);
 GetMem(RgnData, aSize);
 GetRegionData(rgn, aSize, RgnData);
 RgnPtr := @RgnData.Buffer;
 for i := 0 to pred(RgnData.rdh.nCount) do
    begin
    aRect := RgnPtr[i];
    Canvas.Rectangle(aRect);
    end;
 FreeMem(RgnData);
 DeleteObject(rgn);
end;

MechMac666 18. Jun 2012 20:02

AW: Wie kann man mit HRGN arbeiten?
 
Hallo, danke für die Hilfe.

Ja ich muss es automatisieren. Denn da die DXF-Grafiken immer anders sind,
sind auch die Regionen immer anders.
Im nächsten Schritt muss ich also nicht nur die Region zerteilen, ich muss auch irgendwie wieder an die Koordinaten heran.
Wobei ich da theoretisch auch die "Echten" Punkte der DXF auf Screen-Koordinaten umrechnen kann und mittels PtInRegion prüfen kann, ob sie zu einer Region gehören.

Regionen.... Das ist auch schon das Schlüsselwort.
Wie muss ich denn die HRGN verstehen?
Eher als ein Array auf deren jeder "Ebene" ein Sammelsurium aus
Rechtecken einen Teil einer Form (z.B. die einer Polylinie) beschreibt?
Oder ist das nur eine Ebene, wo alles drauf ist?

Konkret zum Beispiel:
Bestehen die vier blauen Teile aus nur einer Polylinie bzw. ich meine gelesen zu haben
das es viele kleine Rechtecke sind? Oder sind sie innerhalb der HRGN getrennt?

Was noch gut zu wissen ist:
Die blauen Bereiche berühren sich nie.
Ich habe mir gedacht, das man mit dieser Informationen das Trennen vielleicht angehen könnte.


Zu Deinem Code. Ich hatte noch nicht die Gelegenheit ihn zu testen. Aber ich habe ihn mir angesehen.
Interessant ist "GetRegionData".
Man scheint ja also tatsächlich irgendwie auf die Daten, die die Region beschreiben, zugreifen zu können.
Allerdings sind es wohl "nur" Rechtecke, da in der Schleife tRect`s zur visualisierung gezeichnet werden.


Gruß, MechMac666

Bummi 18. Jun 2012 20:18

AW: Wie kann man mit HRGN arbeiten?
 
Wenn Du die Punkte schon hast würde ich damit weiterarbeiten, ich habe allerdings keinen Schimmer wo Du hin willst.

MechMac666 18. Jun 2012 21:20

AW: Wie kann man mit HRGN arbeiten?
 
Hm, ja, wahrscheinlich hast Du recht. Ich müsste die ursprünglichen Punkte eh behalten.
Da macht es keinen Sinn die Regions dafür zu verwenden. Ich muss die Bereiche der Außenkontur sowieso selbst trennen,
da kann ich auch gleich bei den Listen bleiben.

Der Grund für das Vorgehen war die Sache mit PtInRegion.
Damit hätte man leicht Kollisionen überprüfen können.
Ich bin mir nicht sicher ob ich das mit Punktelisten hinbekomme.
Anderseits, kann man eine Punkteliste auch mal eben schnell konvertieren und die Funktion PtInRegion für eine schnelle Überprüfung missbrauchen.
Ich denke das ich es so mal probiere.

Gruß, MechMac666

Bummi 18. Jun 2012 21:38

AW: Wie kann man mit HRGN arbeiten?
 
beiliegende Prozedur ist recht flott, ich verwende sie im Mousemove um Hitregions vorzuselektieren (TPointFDynArray nur weil ich es mit GDI+ verwende, ein normales PointArray tut es auch)

Delphi-Quellcode:
function PointInPolygon(const Points: TPointFDynArray; X, Y: Integer): Boolean;
var
  Count, K, J: Integer;
begin
  Result := False;
  J := High(Points);
  for K := 0 to High(Points) do
  begin
    if ((Points[K].Y <= Y) and (Y < Points[J].Y)) or ((Points[J].Y <= Y) and (Y < Points[K].Y)) then
    begin
      if ((Points[J].Y - Points[K].Y)<>0) and (X < (Points[J].X - Points[K].X) * (Y - Points[K].Y) / (Points[J].Y - Points[K].Y) + Points[K].X) then
      begin
        Result := not Result;
      end;
    end;
    J := K;
  end;
end;

Medium 18. Jun 2012 21:41

AW: Wie kann man mit HRGN arbeiten?
 
Test auf "Punkt in Polygon": Ich habe "Solution 2" seit Jahren im Einsatz (bei Komponenten für CM_HITTEST), und es ist trotz der mir eigentlich unliebsamen Trigonometrie robust und flott. Damit könntest du die Regions (wenn sie nur dafür sind) komplett los werden, und mit den für deine restlichen Aufgaben günstigeren Strukturen weiter machen. Zumindest klingt es bisher so, als könnte das ein sinnvoller Tipp sein :)

Edit: Bummis Code schaut nach einer sehr hübschen Umstezung von "Solution 1" aus. Die könnte glatt windschnittiger sein, morgen mal probieren :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 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