Skip to content

Commit 27b086b

Browse files
ADD: refactor RectIntersectRect
1 parent 3f764f9 commit 27b086b

File tree

3 files changed

+118
-56
lines changed

3 files changed

+118
-56
lines changed

data_control/Vectormath/testcase1.pas

+95-36
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,15 @@
6666
Procedure LoadFromSaveToStream;
6767
End;
6868

69-
{ TOtherTests }
69+
{ TGeneralTests }
7070

71-
TOtherTests = Class(TTestCase)
71+
TGeneralTests = Class(TTestCase)
7272
protected
73+
//Procedure SetUp; override;
74+
//Procedure TearDown; override;
7375
published
74-
Procedure Convolve1D;
75-
Procedure ConvolveAVG;
76+
Procedure RectIsInRect;
77+
Procedure RectIsNotInRect;
7678
End;
7779

7880
Implementation
@@ -430,45 +432,103 @@
430432
m.free;
431433
End;
432434

433-
{ TOtherTests }
435+
{ TGeneralTests }
434436

435-
Procedure TOtherTests.Convolve1D;
437+
Procedure TGeneralTests.RectIsInRect;
436438
Var
437-
a, b, c: TVectorN;
439+
TL1, BR1, TL2, BR2: TVector2;
438440
Begin
439441
(*
440-
* Falten mit "nicht symmetrischem" filter kern
442+
* Overlapping Edges
441443
*)
442-
a := VN([1, 2, 3]);
443-
b := VN([4, 5, 6]);
444-
c := Convolve(a, b);
445-
AssertEquals('Invalid len', 5, length(c));
446-
AssertEquals('Invalid result [0]', 4, c[0]);
447-
AssertEquals('Invalid result [1]', 13, c[1]);
448-
AssertEquals('Invalid result [2]', 28, c[2]);
449-
AssertEquals('Invalid result [3]', 27, c[3]);
450-
AssertEquals('Invalid result [4]', 18, c[4]);
444+
TL1 := v2(-1, 1);
445+
BR1 := v2(1, -1);
446+
TL2 := v2(0.5, 2);
447+
BR2 := v2(2, 0.5);
448+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
449+
TL2 := v2(0.5, -2);
450+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
451+
BR2 := v2(-2, -0.5);
452+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
453+
TL2 := v2(-0.5, 2);
454+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
455+
(*
456+
* Overlapping Sides
457+
*)
458+
TL2 := v2(0.5, 0.5);
459+
BR2 := v2(2, -0.5);
460+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
461+
BR2 := v2(-0.5, -2);
462+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
463+
TL2 := v2(-2, 0.5);
464+
BR2 := v2(-0.5, -0.5);
465+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
466+
TL2 := v2(0.5, 2);
467+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
468+
(*
469+
* complete in each other
470+
*)
471+
TL2 := v2(-2, 2);
472+
BR2 := v2(2, -2);
473+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
474+
TL2 := v2(-0.5, 0.5);
475+
BR2 := v2(0.5, -0.5);
476+
AssertTrue(RectIntersectRect(TL1, BR1, TL2, BR2));
451477
End;
452478

453-
Procedure TOtherTests.ConvolveAVG;
479+
Procedure TGeneralTests.RectIsNotInRect;
454480
Var
455-
a, b, c: TVectorN;
481+
TL1, BR1, TL2, BR2: TVector2;
456482
Begin
457-
(*
458-
* Faltung als Mittelwert filter
459-
*)
460-
a := vn([0, 0, 10, 10, 10, 0, 0]);
461-
b := vn([0.5, 0.5]);
462-
c := Convolve(a, b);
463-
AssertEquals('Invalid len', 8, length(c));
464-
AssertEquals('Invalid result [0]', 0, c[0]);
465-
AssertEquals('Invalid result [1]', 0, c[1]);
466-
AssertEquals('Invalid result [2]', 5, c[2]);
467-
AssertEquals('Invalid result [3]', 10, c[3]);
468-
AssertEquals('Invalid result [4]', 10, c[4]);
469-
AssertEquals('Invalid result [5]', 5, c[5]);
470-
AssertEquals('Invalid result [6]', 0, c[6]);
471-
AssertEquals('Invalid result [7]', 0, c[7]);
483+
// Above
484+
TL1 := v2(-1, 1);
485+
BR1 := v2(1, -1);
486+
TL2 := v2(-2.5, 3.5);
487+
BR2 := v2(-1.5, 1.5);
488+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
489+
TL2 := v2(-0.5, 3.5);
490+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
491+
BR2 := v2(0.5, 1.5);
492+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
493+
TL2 := v2(1.5, 3.5);
494+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
495+
BR2 := v2(2.5, 1.5);
496+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
497+
// Side by side
498+
TL2 := v2(-2.5, 3.5); // left
499+
BR2 := v2(-1.5, 1.5);
500+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
501+
TL2 := v2(-2.5, 0.5);
502+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
503+
BR2 := v2(-1.5, -0.5);
504+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
505+
TL2 := v2(-2.5, -1.5);
506+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
507+
BR2 := v2(-1.5, -2.5);
508+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
509+
TL2 := v2(2.5, 3.5); // right
510+
BR2 := v2(1.5, 1.5);
511+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
512+
TL2 := v2(2.5, 0.5);
513+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
514+
BR2 := v2(1.5, -0.5);
515+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
516+
TL2 := v2(2.5, -1.5);
517+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
518+
BR2 := v2(1.5, -2.5);
519+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
520+
// Below
521+
TL2 := v2(-2.5, -3.5);
522+
BR2 := v2(-1.5, -1.5);
523+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
524+
TL2 := v2(-0.5, -3.5);
525+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
526+
BR2 := v2(0.5, -1.5);
527+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
528+
TL2 := v2(1.5, -3.5);
529+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
530+
BR2 := v2(2.5, -1.5);
531+
AssertFalse(RectIntersectRect(TL1, BR1, TL2, BR2));
472532
End;
473533

474534
Initialization
@@ -479,7 +539,6 @@
479539
RegisterTest(TMatrix3x3Tests);
480540
RegisterTest(TMatrix4x4Tests);
481541
RegisterTest(TMatrixNxMTests);
482-
RegisterTest(TOtherTests);
483-
542+
RegisterTest(TGeneralTests);
484543
End.
485544

data_control/uvectormath.pas

+17-18
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
(* InvertMatrix2 for TMatrix4x4, TMatrix2x2 *)
6262
(* 0.18 CalculatePlumbFootPoint *)
6363
(* 0.19 Convolve *)
64+
(* speedup RectIntersectRect code *)
6465
(* *)
6566
(******************************************************************************)
6667
Unit uvectormath;
@@ -2978,24 +2979,22 @@
29782979
End;
29792980

29802981
Function RectIntersectRect(Const TL1, BR1, TL2, BR2: TVector2): Boolean;
2981-
Begin
2982-
result :=
2983-
PointInRect(tl1, tl2, br2) Or
2984-
PointInRect(BR1, tl2, br2) Or
2985-
PointInRect(v2(tl1.x, br1.y), tl2, br2) Or
2986-
PointInRect(v2(br1.x, tl1.y), tl2, br2) Or
2987-
(*
2988-
* Diese Fälle Hier Treten nur auf, wenn alle Punkte des Rechtecks 1 auserhalb des Ersten liegen
2989-
* Dann muss das Rechteck 2 mindestens mit 2 Punkten Innerhalb des 1 Liegen (wäre es nur einer, dann
2990-
* wäre wieder ein Fall von oben gekommen.
2991-
* Den Test auf "Enthalten" sein kann man also mit nur 2 Prüfungen machen. Wichtig die beiden
2992-
* Prüfpunkte müssen sich diagonal gegenüberliegen !
2993-
*)
2994-
PointInRect(tl2, tl1, br1) Or
2995-
PointInRect(BR2, tl1, br1)
2996-
// Or PointInRect(v2(tl2.x, br2.y), tl1, br1) // Diese Beiden Fälle kann man sich sparen
2997-
// Or PointInRect(v2(br2.x, tl2.y), tl1, br1) // Diese Beiden Fälle kann man sich sparen
2998-
;
2982+
Var
2983+
min1, max1, min2, max2: TVector2;
2984+
Begin
2985+
// Inspired by https://www.youtube.com/watch?app=desktop&v=QQx_NmCIuCY&t=0s
2986+
// 1. Sort points
2987+
min1 := minV2(TL1, BR1);
2988+
max1 := maxV2(TL1, BR1);
2989+
min2 := minV2(TL2, BR2);
2990+
max2 := maxV2(TL2, BR2);
2991+
// 2. do the inverted compare ;)
2992+
result := Not (
2993+
(max1.x < min2.x) Or
2994+
(min1.x > max2.x) Or
2995+
(max1.y < min2.y) Or
2996+
(min1.y > max2.y)
2997+
);
29992998
End;
30002999

30013000
Function PointInCube(Const P, TL, BR: Tvector3): Boolean;

graphics/ugraphics.pas

+6-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
math // max, min, arctan2
6262
;
6363

64+
Const
65+
AlphaOpaque = 0;
66+
AlphaTranslucent = 255;
67+
6468
Type
6569
TInterpolationMode = (
6670
imNone, // Keine Interpolierung die Koordinaten werden immer auf trunc und dann direkt ausgegen => nur Sinnvoll bei 1:1 Abtastungen da sonst bildfehler entstehen können
@@ -104,7 +108,7 @@
104108
Function RGB(r, g, b: Byte): TRGB;
105109
Function RGBA(R, G, B, A: Byte): TRGBA;
106110
Function ColorToRGB(c: TColor): TRGB;
107-
Function ColorToRGBA(c: TColor; AlphaValue: byte = 0): TRGBA;
111+
Function ColorToRGBA(c: TColor; AlphaValue: byte = AlphaOpaque): TRGBA;
108112
Function RGBToColor(rgb: TRGB): TColor;
109113
Function RGBAToColor(rgba: TRGBA): TColor;
110114
Function FPColorToColor(Const Color: TFPColor): TColor; // Wandelt eine FPColor in TColor um
@@ -531,7 +535,7 @@
531535

532536
Function RGBAtoLuminanz(Value: TRGBA): Byte;
533537
Begin
534-
//Y = 0.3R + 0.59G + 0.11B
538+
//Y = 0.3R + 0.59G + 0.11B
535539
result := min(255, max(0,
536540
round(
537541
value.R * 0.3 +

0 commit comments

Comments
 (0)