AGB  ·  Datenschutz  ·  Impressum  







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

Zwei Vier-Ecke subtrahieren

Ein Thema von JayZ · begonnen am 21. Feb 2017 · letzter Beitrag vom 20. Mai 2017
Antwort Antwort
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.494 Beiträge
 
Delphi 12 Athens
 
#1

AW: Zwei Vier-Ecke subtrahieren

  Alt 1. Mär 2017, 15:51
Hab ein bischen Zeit gehabt und meine Idee umgesetzt und erfolgreich getestet.
Auf vordefinierte Funktionen wurde verzichtet, der Austausch von TRect durch eine eigene Klasse sollte also kein Problem sein.
Delphi-Quellcode:
unit MathRect;

interface

uses
  Types;

type
  TRectArray = array of TRect;

function Subtract(const R1, R2: TRect): TRectArray;

implementation

function Min(A, B: Integer): Integer;
begin
  if A < B then
    Result := A
  else
    Result := B;
end;

function Max(A, B: Integer): Integer;
begin
  if A > B then
    Result := A
  else
    Result := B;
end;

function IntersectRect(out Rect: TRect; const R1: TRect; const R2: TRect): Boolean;
begin
  Result :=
    (R2.Top < R1.Bottom) and (R1.Top < R2.Bottom) and
    (R2.Left < R1.Right) and (R1.Left < R2.Right);
  if Result then
  begin
    Rect.Top := Max(R1.Top, R2.Top);
    Rect.Left := Max(R1.Left, R2.Left);
    Rect.Bottom := Min(R1.Bottom, R2.Bottom);
    Rect.Right := Min(R1.Right, R2.Right);
  end;
end;

function IsRectEmpty(const Rect: TRect): Boolean;
begin
  Result := (Rect.Left >= Rect.Right) or (Rect.Top >= Rect.Bottom);
end;

procedure AddRect(var RectArr: TRectArray; const Rect: TRect);
var
  n: Integer;
begin
  if IsRectEmpty(Rect) then
    Exit;
  {anfügen}
  for n := 0 to High(RectArr) do
  begin
    {selbe Zeile}
    if (RectArr[n].Top = Rect.Top) and
       (RectArr[n].Bottom = Rect.Bottom) then
    begin
      {rechts}
      if RectArr[n].Right = Rect.Left then
      begin
        RectArr[n].Right := Rect.Right;
        Exit;
      end;
      {links - derzeit auf Grund der Reihenfolge nicht verwendet}
      if RectArr[n].Left = Rect.Right then
      begin
        RectArr[n].Left := Rect.Left;
        Exit;
      end;
    end;
    {selbe Spalte}
    if (RectArr[n].Left = Rect.Left) and
       (RectArr[n].Right = Rect.Right) then
    begin
      {unten}
      if RectArr[n].Bottom = Rect.Top then
      begin
        RectArr[n].Bottom := Rect.Bottom;
        Exit;
      end;
      {oben - derzeit auf Grund der Reihenfolge nicht verwendet}
      if RectArr[n].Top = Rect.Bottom then
      begin
        RectArr[n].Top := Rect.Top;
        Exit;
      end;
    end;
  end;
  {eigenständiges Recheck hinzufügen}
  n := Length(RectArr);
  SetLength(RectArr, n + 1);
  RectArr[n] := Rect;
end;

function Subtract(const R1, R2: TRect): TRectArray;
var
  A: array[0..2, 0..2] of TRect;
  B: TRect;
  x, y: Integer;
begin
  Result := nil;
  {Das tatsächliche Überschneidungsrechteck B ermitteln}
  if not IntersectRect(B, R1, R2) then
  begin
    {keine Überschneidung}
    AddRect(Result, R1);
    Exit;
  end;
  {Zeilen}
  for y := 0 to 2 do
  begin
    A[0, y].Left := R1.Left;
    A[0, y].Right := B.Left;
    A[1, y].Left := B.Left;
    A[1, y].Right := B.Right;
    A[2, y].Left := B.Right;
    A[2, y].Right := R1.Right;
  end;
  {Spalten}
  for x := 0 to 2 do
  begin
    A[x, 0].Top := R1.Top;
    A[x, 0].Bottom := B.Top;
    A[x, 1].Top := B.Top;
    A[x, 1].Bottom := B.Bottom;
    A[x, 2].Top := B.Bottom;
    A[x, 2].Bottom := R1.Bottom;
  end;
  {benachbarte Rechtecke zusammenfassen}
  for y := 0 to 2 do
    for x := 0 to 2 do
      if not ((y = 1) and (x = 1)) then
        AddRect(Result, A[x, y]);
end;

end.
  Mit Zitat antworten Zitat
JayZ

Registriert seit: 14. Mai 2016
34 Beiträge
 
#2

AW: Zwei Vier-Ecke subtrahieren

  Alt 20. Mai 2017, 10:28
Ach sorry Blup ich hab das leider erst jetzt gesehen, ist ja nett das du dir die zeit dafür genommen hast Deine methode ist auch viel simpler und kürzer als das was ich gemacht habe (ist wie gesagt ein echtes if-gewrustel geworden weil mir keine mathematische methode eingefallen ist) werde sie wenn ich zeit habe einbauen und meine rauswerfen und kann somit wichtige bits und bytes einsparen hehe, vielen dank! =)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Zwei Vier-Ecke subtrahieren

  Alt 20. Mai 2017, 10:44
Wenn man solche Dinge nicht neu erfinden will, dann helfen in Windows bereits eingebaute Funktionen wie CombineRgn.

CombineRgn function
Michael Gasser
  Mit Zitat antworten Zitat
JayZ

Registriert seit: 14. Mai 2016
34 Beiträge
 
#4

AW: Zwei Vier-Ecke subtrahieren

  Alt 20. Mai 2017, 10:49
Wenn man solche Dinge nicht neu erfinden will, dann helfen in Windows bereits eingebaute Funktionen wie CombineRgn.

CombineRgn function
wie schon gesagt läuft das projekt auf nem arduino-kompatiblem mikroprozessor, da gibts leider keine windoof api oder delphi rtl
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
778 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Zwei Vier-Ecke subtrahieren

  Alt 20. Mai 2017, 11:33
Oops und ups - Ich werde lesen lernen und melde mich dann wieder.
Michael Gasser
  Mit Zitat antworten Zitat
JayZ

Registriert seit: 14. Mai 2016
34 Beiträge
 
#6

AW: Zwei Vier-Ecke subtrahieren

  Alt 20. Mai 2017, 11:45
Oops und ups - Ich werde lesen lernen und melde mich dann wieder.
Kes problem, mir Bärner si nid die schnöuschte, passiert mir ou oft haha.
  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 04:55 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