Skip to content

Commit

Permalink
Add: IsConvexPolygon
Browse files Browse the repository at this point in the history
  • Loading branch information
slackydev committed Jul 27, 2024
1 parent 4884ead commit a03dd46
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
29 changes: 25 additions & 4 deletions Source/script/imports/simba.import_math.pas
Original file line number Diff line number Diff line change
Expand Up @@ -203,19 +203,39 @@ procedure _LapePolygonArea(const Params: PParamArray; const Result: Pointer); LA
end;

(*
PolygonArea
IsConvexPolygon
-----------
> function IsConvexPolygon(Polygon: TPointArray): Boolean;
Returns if the polygon is convex, order does not matter. A concave polygon will return False.
*)
procedure _LapeIsConvexPolygon(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PBoolean(Result)^ := TSimbaGeometry.IsConvexPolygon(PPointArray(Params^[0])^);
end;

(*
TriangulatePolygon
-----------
> function TriangulatePolygon(Polygon: TPointArray): TTriangleArray;
Break the polygon into triangles, the smallest possible polygon. The order of the
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.
*)
procedure _LapeTriangulatePolygon(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PTriangleArray(Result)^ := TSimbaGeometry.TriangulatePolygon(PPointArray(Params^[0])^);
end;

(*
PolygonArea
LineInPolygon
-----------
> function LineInPolygon(a1, a2: TPoint; const Polygon: TPointArray): Boolean;
> function LineInPolygon(p,q: TPoint; const Polygon: TPointArray): Boolean;
Returns True if the line fits within the bounds of the polygon.
*)
procedure _LapeLineInPolygon(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
Expand Down Expand Up @@ -406,7 +426,8 @@ procedure ImportMath(Compiler: TSimbaScript_Compiler);

addGlobalFunc('function Modulo(const X, Y: Integer): Integer; overload', @_LapeModulo);
addGlobalFunc('function Modulo(const X, Y: Double): Double; overload', @_LapeModuloF);


addGlobalFunc('function IsConvexPolygon(const Polygon: TPointArray): Boolean', @_LapeIsConvexPolygon);
addGlobalFunc('function TriangulatePolygon(const Polygon: TPointArray): TTriangleArray', @_LapeTriangulatePolygon);
addGlobalFunc('function LineInPolygon(a1, a2: TPoint; const Polygon: TPointArray): Boolean', @_LapeLineInPolygon);

Expand Down
25 changes: 25 additions & 0 deletions Source/simba.geometry.pas
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
- PointInEllipse
- AngleBetween
- DeltaAngle
- IsConvexPolygon
- LineInPolygon
- TriangulatePolygon
}

{
Expand Down Expand Up @@ -43,6 +46,7 @@ TSimbaGeometry = class
public
class constructor Create;

class function IsConvexPolygon(const Polygon: TPointArray): Boolean;
class function LineInPolygon(a1, a2: TPoint; const Polygon: TPointArray): Boolean;
class function TriangulatePolygon(Polygon: TPointArray): TTriangleArray;
class function PolygonArea(const Polygon: TPointArray): Double; static; inline;
Expand Down Expand Up @@ -348,6 +352,27 @@ class function TSimbaGeometry.PointInEllipse(const P, Center: TPoint; const YRad
Result := (Sqr(X) * Sqr(YRadius)) + (Sqr(Y) * Sqr(XRadius)) <= (Sqr(YRadius) * Sqr(XRadius));
end;

class function TSimbaGeometry.IsConvexPolygon(const Polygon: TPointArray): Boolean;
var
i,d: Int32;
a,b,c: TPoint;
begin
if Length(Polygon) = 0 then Exit(False);

d := CrossProduct(Polygon[i],Polygon[(i+1) mod Length(Polygon)],Polygon[(i+2) mod Length(Polygon)]);
for i:=0 to High(Polygon) do
begin
A := Polygon[i];
B := Polygon[(i+1) mod Length(Polygon)];
C := Polygon[(i+2) mod Length(Polygon)];

if CrossProduct(A,B,C)*d <= 0 then
Exit(False);
end;

Result := True;
end;

class function TSimbaGeometry.LineInPolygon(a1, a2: TPoint; const Polygon: TPointArray): Boolean;
var
i: Int32;
Expand Down

0 comments on commit a03dd46

Please sign in to comment.