Skip to content

Commit

Permalink
Polygon.Connect, String.ExtractNumbers, Fix ConcaveHull
Browse files Browse the repository at this point in the history
  • Loading branch information
slackydev committed Jan 10, 2025
1 parent 75a54df commit d1ca6f9
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 11 deletions.
40 changes: 32 additions & 8 deletions Source/script/imports/simba.import_polygon.pas
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ implementation
Polygon
=======
Polygon type
Note:
Polygon variable can be cast into a TPointArray in order to use it with TPointArray methods.
*)

(*
Expand All @@ -46,6 +49,7 @@ procedure _LapePolygon_Bounds(const Params: PParamArray; const Result: Pointer);
```
function TPolygon.Mean: TPoint;
```
Returns the mean, or rather the centroid of the polygon.
*)
procedure _LapePolygon_Mean(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
Expand All @@ -58,6 +62,7 @@ procedure _LapePolygon_Mean(const Params: PParamArray; const Result: Pointer); L
```
function TPolygon.Area: Double;
```
Computes the area of the polygon.
*)
procedure _LapePolygon_Area(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
Expand All @@ -68,7 +73,7 @@ procedure _LapePolygon_Area(const Params: PParamArray; const Result: Pointer); L
TPolygon.IsConvex
-----------------
```
function TPolygon.IsConvex(Polygon: TPointArray): Boolean;
function TPolygon.IsConvex: Boolean;
```
Returns if the polygon is convex, order does not matter. A concave polygon will return False.
*)
Expand Down Expand Up @@ -97,6 +102,7 @@ procedure _LapePolygon_Contains(const Params: PParamArray; const Result: Pointer
function TPolygon.ContainsLine(p,q: TPoint): Boolean;
```
Returns True if the line fits within the bounds of the polygon.
This is determined by checking if the line crosses any of the vertices.
*)
procedure _LapePolygon_ContainsLine(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
Expand Down Expand Up @@ -138,7 +144,7 @@ function TPolygon.Triangulate(MinArea: Double = 0; MaxDepth: Int32 = 0): TTriang
input does matter, if it fails, try to reverse the Poly with Poly.Reversed()
This is a custom algorithm by slacky, based around the concept of trimming "ears",
if you dont like the output, you may have more luck with rolling the Polygon before calling.
if you dont like the output, you may have luck with rolling the Polygon before calling.
Two default params exists as well, `MinArea` and `MaxDepth`, they work in tandom,
`MinArea` parameter is for setting a minimum size of triangles added to result, and as this method
Expand All @@ -153,9 +159,10 @@ procedure _LapePolygon_Triangulate(const Params: PParamArray; const Result: Poin
(*
TPolygon.DouglasPeucker
-----------------------
> function TPolygon.DouglasPeucker(Epsilon: Double): TPolygon;
Returns the two points that are furthest away from eachother in a polygon.
```
function TPolygon.DouglasPeucker(Epsilon: Double): TPolygon;
```
Attempts to simplify the polygon by trimming vertices.
*)
procedure _LapePolygon_DouglasPeucker(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
Expand All @@ -165,15 +172,31 @@ procedure _LapePolygon_DouglasPeucker(const Params: PParamArray; const Result: P
(*
TPolygon.FurthestPoints
-----------------------
> procedure TPolygon.FurthestPoints(out A,B: TPoint);
```
procedure TPolygon.FurthestPoints(out A,B: TPoint);
```
Returns the two points that are furthest away from eachother in a polygon.
*)
procedure _LapePolygon_FurthestPoints(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PPolygon(Params^[0])^.FurthestPoints(PPoint(Params^[1])^, PPoint(Params^[2])^);
end;

(*
TPolygon.Connect
-----------------
```
function TPolygon.Connect: TPointArray;
```
Connects the polygon vertices in order to make a TPointArray bounding shape.
*)
procedure _LapePolygon_Connect(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
TPointArray(Result^) := PPolygon(Params^[0])^.Connect;
end;



procedure _LapePoint_IN_Polygon(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PBoolean(Result)^ := PPoint(Params^[0])^ in PPolygon(Params^[1])^;
Expand All @@ -199,7 +222,8 @@ procedure ImportPolygon(Script: TSimbaScript);
addGlobalFunc('function TPolygon.Triangulate(MinArea: Single; MaxDepth: Int32): TTriangleArray;', @_LapePolygon_Triangulate);
addGlobalFunc('function TPolygon.DouglasPeucker(Epsilon: Double): TPolygon;', @_LapePolygon_DouglasPeucker);
addGlobalFunc('procedure TPolygon.FurthestPoints(out A, B: TPoint);', @_LapePolygon_FurthestPoints);

addGlobalFunc('function TPolygon.Connect: TPointArray', @_LapePolygon_Connect);

addGlobalFunc('operator in(Left: TPoint; Right: TPolygon): Boolean;', @_LapePoint_IN_Polygon);

DumpSection := '';
Expand Down
18 changes: 17 additions & 1 deletion Source/script/imports/simba.import_string.pas
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,21 @@ procedure _LapeString_ExtractFloat(const Params: PParamArray; const Result: Poin
PDouble(Result)^ := PString(Params^[0])^.ExtractFloat(PInt64(Params^[1])^);
end;

(*
String.ExtractNumbers
---------------------
```
function String.ExtractNumbers(): TStringArray;
```
Extract all the numbers found in the string.
The result is a an array of strings, where each string contains a number
extracted from the string. You can now use .ToFloat or .ToInteger on it.
*)
procedure _LapeString_ExtractNumbers(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
TStringArray(Result^) := String(Params^[0]^).ExtractNumbers();
end;

(*
String.IsAlpha
--------------
Expand Down Expand Up @@ -1244,7 +1259,8 @@ procedure ImportString(Script: TSimbaScript);
addGlobalFunc('function String.Extract(Chars: array of Char): String;', @_LapeString_Extract);
addGlobalFunc('function String.ExtractInteger(Default: Int64 = -1): Int64;', @_LapeString_ExtractInteger);
addGlobalFunc('function String.ExtractFloat(Default: Double = -1): Double;', @_LapeString_ExtractFloat);

addGlobalFunc('function String.ExtractNumbers(): TStringArray;', @_LapeString_ExtractNumbers);

addGlobalFunc('function String.Trim: String; overload;', @_LapeString_Trim);
addGlobalFunc('function String.Trim(TrimChars: array of Char): String; overload;', @_LapeString_TrimEx);

Expand Down
4 changes: 2 additions & 2 deletions Source/simba.vartype_pointarray.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2723,8 +2723,8 @@ function TPointArrayHelper.ConcaveHull(Epsilon:Double=2.5; kCount:Int32=5): TPol

Buffer.Add(pts);
end;

Result := TPolygon(Buffer.ToArray(False)).DouglasPeucker(Max(2, Epsilon/2));
Result := TPolygon(TPointArray(Buffer.ToArray(False)).Border()).DouglasPeucker(Max(2, Epsilon/2));
end;

(*
Expand Down
23 changes: 23 additions & 0 deletions Source/simba.vartype_polygon.pas
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ interface
function DouglasPeucker(Epsilon: Double): TPolygon;
procedure FurthestPoints(out A,B: TPoint);
function Triangulate(MinArea: Single = 0; MaxDepth: Int32 = 0): TTriangleArray;
function Connect: TPointArray;
end;

PPolygon = ^TPolygon;
Expand All @@ -49,6 +50,7 @@ implementation
Math,
simba.math,
simba.geometry,
simba.containers,
simba.vartype_point,
simba.vartype_pointarray;

Expand Down Expand Up @@ -337,6 +339,27 @@ function TPolygonHelper.Triangulate(MinArea: Single; MaxDepth: Int32): TTriangle
end;
end;

function TPolygonHelper.Connect: TPointArray;
var
I: Integer;
Buffer: TSimbaPointBuffer;
begin
Buffer.Init();

if (Length(Self) > 1) then
begin
for I := 0 to High(Self) - 1 do
begin
Buffer.Add(TPointArray.CreateFromLine(Self[I], Self[I+1]));
Buffer.Pop(); // dont duplicate self[I+1]
end;
Buffer.Add(TPointArray.CreateFromLine(Self[High(Self)], Self[0]));
Buffer.Pop(); // dont duplicate self[0]
end;

Result := Buffer.ToArray(False);
end;

operator in(const P: TPoint; const Poly: TPolygon): Boolean;
begin
Result := Poly.Contains(P);
Expand Down
39 changes: 39 additions & 0 deletions Source/simba.vartype_string.pas
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ TRegExprMatch = record
function Extract(const Chars: array of Char): String;
function ExtractInteger(Default: Int64 = -1): Int64;
function ExtractFloat(Default: Double = -1): Double;
function ExtractNumbers(): TStringArray;

function Trim: String; overload;
function Trim(const TrimChars: array of Char): String; overload;
Expand Down Expand Up @@ -742,6 +743,44 @@ function TSimbaStringHelper.ExtractFloat(Default: Double): Double;
Result := StrToFloatDef(Self.Extract(['.','-','0','1','2','3','4','5','6','7','8','9']), Default);
end;

(*
String.ExtractNumbers
---------------------
```
function String.ExtractNumbers(): TStringArray;
```
Extract all the numbers found in the string.
The result is a an array of strings, where each string contains a number
extracted from the string. You can now use .ToFloat or .ToInteger on it.
*)
function TSimbaStringHelper.ExtractNumbers(): TStringArray;
var
i,c,l: Int32;
function Next(var i: Int32): Int32; begin Inc(i);Result:=i; end;
begin
c := 0;
L := Length(Self);
i := 1;
while i <= Length(Self) do
begin
if Self[i] in ['0'..'9'] then
begin
SetLength(Result, c+1);

Result[c] := Self[i];
while (Next(i) <= L) and (Self[i] in ['0'..'9']) do Result[c] += Self[i];
if (i <= L) and (Self[i] = '.') then
begin
Result[c] += Self[i];
while (Next(i) <= L) and (Self[i] in ['0'..'9']) do Result[c] += Self[i];
end;
if (i > L) then Break;
Inc(c);
end;
Inc(i);
end;
end;

function TSimbaStringHelper.Trim: String;
begin
Result := SysUtils.Trim(Self);
Expand Down

0 comments on commit d1ca6f9

Please sign in to comment.