22
33(* ******************************************************************************
44* Author : Angus Johnson *
5- * Date : 22 November 2024 *
5+ * Date : 10 May 2025 *
66* Website : https://www.angusj.com *
77* Copyright : Angus Johnson 2010-2024 *
88* Purpose : Core Clipper Library module *
@@ -325,6 +325,7 @@ function GetSegmentIntersectPt(const ln1a, ln1b, ln2a, ln2b: TPoint64;
325325 out ip: TPoint64): Boolean;
326326
327327function PointInPolygon (const pt: TPoint64; const polygon: TPath64): TPointInPolygonResult;
328+ function Path2ContainsPath1 (const path1, path2: TPath64): Boolean;
328329
329330function GetClosestPointOnSegment (const pt, seg1, seg2: TPoint64): TPoint64;
330331 { $IFDEF INLINING} inline; { $ENDIF}
@@ -375,7 +376,7 @@ function Iif(eval: Boolean; trueVal, falseVal: double): double; overload;
375376implementation
376377
377378resourcestring
378- rsClipper_PrecisonErr = ' The decimal rounding value is invalid' ;
379+ rsClipper_PrecisionErr = ' The decimal rounding value is invalid' ;
379380
380381// ------------------------------------------------------------------------------
381382// TRect64 methods ...
@@ -485,7 +486,7 @@ function TRectD.GetIsValid: Boolean;
485486
486487function TRectD.GetMidPoint : TPointD;
487488begin
488- result := PointD((Left + Right) *0.5 , (Top + Bottom) *0.5 );
489+ result := PointD((Left + Right) * 0.5 , (Top + Bottom) * 0.5 );
489490end ;
490491// ------------------------------------------------------------------------------
491492
@@ -556,7 +557,7 @@ function TListEx.Add(item: Pointer): integer;
556557 begin
557558 if fCapacity = 0 then
558559 fCapacity := 16 else
559- fCapacity := fCapacity *2 ;
560+ fCapacity := fCapacity * 2 ;
560561 SetLength(fList, fCapacity);
561562 end ;
562563 fList[fCount] := item;
@@ -707,7 +708,7 @@ function Iif(eval: Boolean; trueVal, falseVal: double): double;
707708procedure CheckPrecisionRange (var precision: integer);
708709begin
709710 if (precision < -MaxDecimalPrecision) or (precision > MaxDecimalPrecision) then
710- Raise EClipper2LibException(rsClipper_PrecisonErr );
711+ Raise EClipper2LibException(rsClipper_PrecisionErr );
711712end ;
712713// ------------------------------------------------------------------------------
713714
@@ -1215,7 +1216,7 @@ function ReversePath(const path: TPath64): TPath64;
12151216 i, highI: Integer;
12161217begin
12171218 highI := high(path);
1218- SetLength(Result, highI +1 );
1219+ SetLength(Result, highI + 1 );
12191220 for i := 0 to highI do
12201221 Result[i] := path[highI - i];
12211222end ;
@@ -1226,7 +1227,7 @@ function ReversePath(const path: TPathD): TPathD;
12261227 i, highI: Integer;
12271228begin
12281229 highI := high(path);
1229- SetLength(Result, highI +1 );
1230+ SetLength(Result, highI + 1 );
12301231 for i := 0 to highI do
12311232 Result[i] := path[highI - i];
12321233end ;
@@ -1241,7 +1242,7 @@ function ReversePaths(const paths: TPaths64): TPaths64;
12411242 for i := 0 to i -1 do
12421243 begin
12431244 highJ := high(paths[i]);
1244- SetLength(Result[i], highJ+ 1 );
1245+ SetLength(Result[i], highJ + 1 );
12451246 for j := 0 to highJ do
12461247 Result[i][j] := paths[i][highJ - j];
12471248 end ;
@@ -1254,10 +1255,10 @@ function ReversePaths(const paths: TPathsD): TPathsD;
12541255begin
12551256 i := length(paths);
12561257 SetLength(Result, i);
1257- for i := 0 to i -1 do
1258+ for i := 0 to i - 1 do
12581259 begin
12591260 highJ := high(paths[i]);
1260- SetLength(Result[i], highJ+ 1 );
1261+ SetLength(Result[i], highJ + 1 );
12611262 for j := 0 to highJ do
12621263 Result[i][j] := paths[i][highJ - j];
12631264 end ;
@@ -1276,8 +1277,8 @@ function ShiftPath(const path: TPath64; shift: integer): TPath64;
12761277 if shift = 0 then Exit;
12771278 if shift < 0 then shift := len + shift;
12781279 diff := len - shift;
1279- Move(path[shift], Result[0 ], diff *SizeOf(TPoint64));
1280- Move(path[0 ], Result[diff], shift *SizeOf(TPoint64));
1280+ Move(path[shift], Result[0 ], diff * SizeOf(TPoint64));
1281+ Move(path[0 ], Result[diff], shift * SizeOf(TPoint64));
12811282end ;
12821283// ------------------------------------------------------------------------------
12831284
@@ -1293,8 +1294,8 @@ function ShiftPath(const path: TPathD; shift: integer): TPathD;
12931294 if shift = 0 then Exit;
12941295 if shift < 0 then shift := len + shift;
12951296 diff := len - shift;
1296- Move(path[shift], Result[0 ], diff *SizeOf(TPointD));
1297- Move(path[0 ], Result[diff], shift *SizeOf(TPointD));
1297+ Move(path[shift], Result[0 ], diff * SizeOf(TPointD));
1298+ Move(path[0 ], Result[diff], shift * SizeOf(TPointD));
12981299end ;
12991300// ------------------------------------------------------------------------------
13001301
@@ -2043,20 +2044,20 @@ function CleanPath(const path: TPath64): TPath64;
20432044 Result := nil ;
20442045 len := Length(path);
20452046 while (len > 2 ) and
2046- (IsCollinear(path[len-2 ], path[len- 1 ], path[0 ])) do dec(len);
2047+ (IsCollinear(path[len-2 ], path[len - 1 ], path[0 ])) do dec(len);
20472048 SetLength(Result, len);
20482049 if (len < 2 ) then Exit;
20492050 prev := path[len -1 ];
20502051 j := 0 ;
20512052 for i := 0 to len -2 do
20522053 begin
2053- if IsCollinear(prev, path[i], path[i+ 1 ]) then Continue;
2054+ if IsCollinear(prev, path[i], path[i + 1 ]) then Continue;
20542055 Result[j] := path[i];
20552056 inc(j);
20562057 prev := path[i];
20572058 end ;
2058- Result[j] := path[len -1 ];
2059- SetLength(Result, j+ 1 );
2059+ Result[j] := path[len - 1 ];
2060+ SetLength(Result, j + 1 );
20602061end ;
20612062// ------------------------------------------------------------------------------
20622063
@@ -2213,6 +2214,38 @@ function PointInPolygon(const pt: TPoint64;
22132214// ------------------------------------------------------------------------------
22142215{ $R+}
22152216
2217+ function Path2ContainsPath1 (const path1, path2: TPath64): Boolean;
2218+ var
2219+ i : integer;
2220+ mp : TPoint64;
2221+ pip : TPointInPolygonResult;
2222+ begin
2223+ // precondition: paths must not intersect, except for
2224+ // transient (and presumed 'micro') path intersections
2225+ Result := false;
2226+ pip := pipOn;
2227+ for i := 0 to High(path1) do
2228+ begin
2229+ case PointInPolygon(path1[i], path2) of
2230+ pipOutside:
2231+ begin
2232+ if (pip = pipOutside) then Exit;
2233+ pip := pipOutside;
2234+ end ;
2235+ pipInside:
2236+ begin
2237+ if (pip = pipInside) then begin Result := true; Exit; end ;
2238+ pip := pipInside;
2239+ end ;
2240+ end ;
2241+ end ;
2242+ if (pip <> pipInside) then Exit;
2243+ // result is likely true but check midpoint
2244+ mp := GetBounds(path1).MidPoint;
2245+ Result := PointInPolygon(mp, path2) = pipInside;
2246+ end ;
2247+ // ------------------------------------------------------------------------------
2248+
22162249procedure GetSinCos (angle: double; out sinA, cosA: double);
22172250 { $IFDEF INLINE} inline; { $ENDIF}
22182251{ $IFNDEF FPC}
0 commit comments