Skip to content

Commit

Permalink
Tweak MinAreaCircle
Browse files Browse the repository at this point in the history
  • Loading branch information
ollydev committed Sep 21, 2023
1 parent 71a30c5 commit 6d5ae83
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 106 deletions.
6 changes: 3 additions & 3 deletions Source/script/imports/simba/simba.import_circle.pas
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ implementation
*)
procedure _LapeCircle_Create(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PCircle(Result)^ := TCircle.Create(PPoint(Params^[0])^, PInteger(Params^[1])^);
PCircle(Result)^ := TCircle.Create(PInteger(Params^[0])^, PInteger(Params^[1])^, PInteger(Params^[2])^);
end;

(*
Expand Down Expand Up @@ -199,10 +199,10 @@ procedure ImportCircle(Compiler: TSimbaScript_Compiler);
begin
ImportingSection := 'TCircle';

addGlobalType('record Center: TPoint; Radius: Integer; end;', 'TCircle');
addGlobalType('record X, Y, Radius: Integer; end;', 'TCircle');
addGlobalType('array of TCircle;', 'TCircleArray');

addGlobalFunc('function TCircle.Create(ACenter: TPoint; ARadius: Integer): TCircle; static; overload', @_LapeCircle_Create);
addGlobalFunc('function TCircle.Create(X, Y, Radius: Integer): TCircle; static; overload', @_LapeCircle_Create);
addGlobalFunc('function TCircle.CreateFromPoints(Points: TPointArray): TCircle; static; overload', @_LapeCircle_CreateFromPoints);

addGlobalFunc('function TCircle.ToTPA(Filled: Boolean): TPointArray', @_LapeCircle_ToTPA);
Expand Down
10 changes: 5 additions & 5 deletions Source/script/imports/simbaclasses/simba.import_class_image.pas
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,11 @@ procedure _LapeImage_DrawLine(const Params: PParamArray); LAPE_WRAPPER_CALLING_C
(*
TImage.DrawLine
~~~~~~~~~~~~~~~
> procedure TImage.DrawLine(Start, Stop: TPoint; Color: TColor);
> procedure TImage.DrawLine(Start, Stop: TPoint; Thickness: Integer; Color: TColor);
*)
procedure _LapeImage_DrawLineEx(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaImage(Params^[0])^.DrawLine(PPoint(Params^[1])^, PPoint(Params^[2])^, PColor(Params^[3])^);
PSimbaImage(Params^[0])^.DrawLine(PPoint(Params^[1])^, PPoint(Params^[2])^, PInteger(Params^[3])^, PColor(Params^[4])^);
end;

(*
Expand Down Expand Up @@ -1316,8 +1316,8 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('procedure TImage.DrawATPA(ATPA: T2DPointArray; Color: TColor = -1)', @_LapeImage_DrawATPA);
addGlobalFunc('procedure TImage.DrawTPA(TPA: TPointArray; Color: TColor);', @_LapeImage_DrawTPA);

addGlobalFunc('procedure TImage.DrawCrosshairs(ACenter: TPoint; Size: Integer; Thickness: Integer; Color: TColor);', @_LapeImage_DrawCrosshairs);
addGlobalFunc('procedure TImage.DrawCross(ACenter: TPoint; Radius: Integer; Thickness: Integer; Color: TColor);', @_LapeImage_DrawCross);
addGlobalFunc('procedure TImage.DrawCrosshairs(ACenter: TPoint; Size: Integer; Color: TColor);', @_LapeImage_DrawCrosshairs);
addGlobalFunc('procedure TImage.DrawCross(ACenter: TPoint; Radius: Integer; Color: TColor);', @_LapeImage_DrawCross);

addGlobalFunc('procedure TImage.DrawLine(Start, Stop: TPoint; Color: TColor); overload', @_LapeImage_DrawLine);
addGlobalFunc('procedure TImage.DrawLine(Start, Stop: TPoint; Thickness: Integer; Color: TColor); overload', @_LapeImage_DrawLineEx);
Expand All @@ -1342,7 +1342,7 @@ procedure ImportSimbaImage(Compiler: TSimbaScript_Compiler);
addGlobalFunc('procedure TImage.DrawBoxArray(Boxes: TBoxArray; Filled: Boolean; Color: TColor = -1);', @_LapeImage_DrawBoxArray);
addGlobalFunc('procedure TImage.DrawPolygonArray(Polygons: T2DPointArray; Filled: Boolean; Color: TColor = -1);', @_LapeImage_DrawPolygonArray);
addGlobalFunc('procedure TImage.DrawCircleArray(Circles: TCircleArray; Filled: Boolean; Color: TColor = -1);', @_LapeImage_DrawCircleArray);
addGlobalFunc('procedure TImage.DrawCrossArray(Points: TPointArray; Radius: Integer; Thickness: Integer; Color: TColor = -1);', @_LapeImage_DrawCrossArray);
addGlobalFunc('procedure TImage.DrawCrossArray(Points: TPointArray; Radius: Integer; Color: TColor = -1);', @_LapeImage_DrawCrossArray);

addGlobalFunc('procedure TImage.DrawHSLCircle(ACenter: TPoint; Radius: Integer)', @_LapeImage_DrawHSLCircle);

Expand Down
28 changes: 19 additions & 9 deletions Source/simba.circle.pas
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,24 @@ interface
type
PCircle = ^TCircle;
TCircle = record
Center: TPoint;
X: Integer;
Y: Integer;
Radius: Integer;
end;
PCircleArray = ^TCircleArray;
TCircleArray = array of TCircle;

TCircleHelper = type helper for TCircle
public const
DEFAULT_VALUE: TCircle = (Center: (X: 0; Y: 0); Radius: 0);
ZERO: TCircle = (X: 0; Y: 0; Radius: 0);
public
class function Create(ACenter: TPoint; ARadius: Integer): TCircle; static;
class function Create(AX, AY: Integer; ARadius: Integer): TCircle; static;
class function CreateFromPoints(Points: TPointArray): TCircle; static;

function Center: TPoint; inline;
function Contains(const P: TPoint): Boolean;
function Bounds: TBox;
function ToTPA(Filled: Boolean): TPointArray;
function Contains(const P: TPoint): Boolean; inline;
function PointAtDegrees(Degrees: Double): TPoint;
function Circumference: Double;
function Area: Double;
Expand All @@ -49,11 +51,12 @@ implementation

uses
Math,
simba.tpa, simba.random, simba.overallocatearray;
simba.math, simba.tpa, simba.random, simba.overallocatearray;

class function TCircleHelper.Create(ACenter: TPoint; ARadius: Integer): TCircle;
class function TCircleHelper.Create(AX, AY: Integer; ARadius: Integer): TCircle;
begin
Result.Center := ACenter;
Result.X := AX;
Result.Y := AY;
Result.Radius := ARadius;
end;

Expand All @@ -62,6 +65,12 @@ class function TCircleHelper.CreateFromPoints(Points: TPointArray): TCircle;
Result := Points.MinAreaCircle();
end;

function TCircleHelper.Center: TPoint;
begin
Result.X := X;
Result.Y := Y;
end;

function TCircleHelper.Bounds: TBox;
begin
Result := TBox.Create(Center, Radius, Radius);
Expand All @@ -74,7 +83,7 @@ function TCircleHelper.ToTPA(Filled: Boolean): TPointArray;

function TCircleHelper.Contains(const P: TPoint): Boolean;
begin
Result := Hypot(P.X - Self.Center.X, P.Y - Self.Center.Y) <= Self.Radius;
Result := DistanceF(X, Y, P.X, P.Y) <= Radius;
end;

function TCircleHelper.PointAtDegrees(Degrees: Double): TPoint;
Expand Down Expand Up @@ -102,7 +111,8 @@ function TCircleHelper.Expand(Amount: Integer): TCircle;
function TCircleHelper.Offset(P: TPoint): TCircle;
begin
Result := Self;
Result.Center := Result.Center.Offset(P);
Result.X += P.X;
Result.Y += P.Y;
end;

function TCircleHelper.Extract(Points: TPointArray): TPointArray;
Expand Down
71 changes: 70 additions & 1 deletion Source/simba.image.pas
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ TSimbaImage = class(TSimbaBaseClass)
procedure DrawCrosshairs(ACenter: TPoint; Size: Integer; Color: TColor);
procedure DrawCross(ACenter: TPoint; Radius: Integer; Color: TColor);

procedure DrawLine(Start, Stop: TPoint; Color: TColor);
procedure DrawLine(Start, Stop: TPoint; Color: TColor); overload;
procedure DrawLine(Start, Stop: TPoint; Thickness: Integer; Color: TColor); overload;

procedure DrawPolygon(Points: TPointArray; Color: TColor);
procedure DrawPolygonFilled(Points: TPointArray; Color: TColor);
Expand Down Expand Up @@ -902,6 +903,74 @@ procedure TSimbaImage.DrawLine(Start, Stop: TPoint; Color: TColor);
end;
end;

procedure TSimbaImage.DrawLine(Start, Stop: TPoint; Thickness: Integer; Color: TColor);
var
BGR: TColorBGRA;
Templ: TPointArray;
H: Integer;

procedure PutPixel(const X, Y: Single); inline;
var
XX, YY: Integer;
I: Integer;
P: TPoint;
begin
XX := Round(X);
YY := Round(Y);

for I := 0 to H do
begin
P.X := XX + Templ[I].X;
P.Y := YY + Templ[I].Y;
if (P.X >= 0) and (P.Y >= 0) and (P.X < FWidth) and (P.Y < FHeight) then
FData[P.Y * FWidth + P.X] := BGR;
end;
end;

var
DX, DY, Step, I: Integer;
RX, RY, X, Y: Single;
begin
if (Thickness <= 1) then
begin
DrawLine(Start, Stop, Color);
Exit;
end;

BGR := ColorToBGRA(Color);

Templ := TPointArray.CreateFromCircle(TPoint.Create(0,0), Thickness, True);
H := High(Templ);

DX := (Stop.X - Start.X);
DY := (Stop.Y - Start.Y);
if (Abs(DX) > Abs(DY)) then
Step := Abs(DX)
else
Step := Abs(DY);

if (Step = 0) then
begin
RX := DX;
RY := DY;
end else
begin
RX := DX / Step;
RY := DY / Step;
end;
X := Start.X;
Y := Start.Y;

PutPixel(X, Y);
for I := 1 to Step do
begin
X := X + RX;
Y := Y + RY;

PutPixel(X, Y);
end;
end;

procedure TSimbaImage.DrawPolygon(Points: TPointArray; Color: TColor);
begin
Self.DrawTPA(Points.Connect(), Color);
Expand Down
7 changes: 7 additions & 0 deletions Source/simba.math.pas
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ interface
SQRT_3 = Double(1.73205080756888);
SQRT_5 = Double(2.23606797749979);

function DistanceF(const X1,Y1,X2,Y2: Double): Double; inline;

function Distance(const X1, Y1, X2, Y2: Integer): Integer; inline; overload;
function Distance(const P1, P2: TPoint): Integer; inline; overload;
function NextPower2(const n: Integer): Integer;
Expand Down Expand Up @@ -75,6 +77,11 @@ function NextPower2(const n: Integer): Integer;
Result := Result + 1;
end;

function DistanceF(const X1, Y1, X2, Y2: Double): Double;
begin
Result := Sqrt(Sqr(Double(X2) - Double(X1)) + Sqr(Double(Y2) - Double(Y1)));
end;

function Distance(const X1, Y1, X2, Y2: Integer): Integer;
begin
Result := Round(Sqrt(Sqr(ValReal(X2) - ValReal(X1)) + Sqr(ValReal(Y2) - ValReal(Y1)))); // convert to ValReal to prevent integer overflows
Expand Down
31 changes: 0 additions & 31 deletions Source/simba.mufasatypes.pas
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,6 @@ function Max(const A, B: Single): Single; inline; overload;
function Min(const A, B: Double): Double; inline; overload;
function Max(const A, B: Double): Double; inline; overload;

function Min(const A, B, C: Integer): Integer; inline; overload;
function Max(const A, B, C: Integer): Integer; inline; overload;

procedure Swap(var A, B: Byte); overload;
procedure Swap(var A, B: Integer); overload;
procedure Swap(var A, B: Single); overload;
Expand Down Expand Up @@ -635,34 +632,6 @@ function Max(const A, B: Double): Double;
Result := B;
end;

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

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

procedure Swap(var A, B: Byte);
begin
specialize Swap<Byte>(A, B);
Expand Down
Loading

0 comments on commit 6d5ae83

Please sign in to comment.