@@ -10,6 +10,7 @@ program Test_DLL;
1010
1111uses
1212 Windows,
13+ Math,
1314 ShellApi,
1415 SysUtils,
1516 { $IFDEF USING_CLIPPER2_SRC}
@@ -475,13 +476,6 @@ begin
475476 end ;
476477end ;
477478
478- function RectToPath64 (const rec: TRect64): TPath64;
479- begin
480- with rec do
481- Result := MakePath64([left, top, right, top,
482- right, bottom, left, bottom]);
483- end ;
484-
485479procedure WriteCPath64 (p: CPath64);
486480var
487481 i, len: integer;
@@ -798,23 +792,25 @@ begin
798792 DisposeLocalCPathsD(cclp_local);
799793end ;
800794
801- procedure Test_InflatePaths64 ( delta: double);
795+ procedure Test_InflatePathsD (edgeCnt: integer; delta: double);
802796var
803- sub: TPaths64 ;
804- csub_local: CPaths64 ;
805- csol_extern: CPaths64 ;
797+ sub: TPathsD ;
798+ csub_local: CPathsD ;
799+ csol_extern: CPathsD ;
806800 svg: TSvgWriter;
807801begin
808802 // setup
809803 WriteLn(#10 ' Testing InflatePaths64' );
810804 SetLength(sub, 1 );
811- sub[0 ] := MakeRandomPath(displayWidth, displayHeight, 7 );
812- // convert path into DLL structure (will require local clean up)
813- csub_local := TPaths64ToCPaths64(sub);
805+ sub[0 ] := MakeRandomPathD(displayWidth, displayHeight, edgeCnt);
806+ // and because offsetting self-intersecting paths is unpredictable ...
807+ sub := Union(sub, frNonZero);
808+ // convert path into required DLL structure (also requires local clean up)
809+ csub_local := TPathsDToCPathsD(sub);
814810
815811 // do the DLL operation
816- csol_extern := InflatePaths64 (csub_local, delta,
817- UInt8(TJoinType.jtMiter ), UInt8(TEndType.etPolygon), 2 , 4 );
812+ csol_extern := InflatePathsD (csub_local, delta,
813+ UInt8(TJoinType.jtRound ), UInt8(TEndType.etPolygon), 2 , 4 );
818814
819815 // optionally display result on the console
820816 // WriteCPaths64(csol_extern);
@@ -823,66 +819,102 @@ begin
823819 svg := TSvgWriter.Create(frNonZero);
824820 try
825821 AddSubject(svg, sub);
826- AddSolution(svg, CPaths64ToPaths64 (csol_extern));
822+ AddSolution(svg, CPathsDToPathsD (csol_extern));
827823 SaveSvg(svg, ' InflatePaths64.svg' , displayWidth, displayHeight);
828824 ShowSvgImage(' InflatePaths64.svg' );
829825 finally
830826 svg.Free;
831827 end ;
832828
833- DisposeLocalCPaths64(csub_local);
834- DisposeExportedCPaths64(csol_extern);
829+ DisposeLocalCPathsD(csub_local);
830+ DisposeExportedCPathsD(csol_extern);
831+ end ;
832+
833+ function RotatePath (const path: TPathD;
834+ const focalPoint: TPointD; angle: double): TPathD;
835+ var
836+ i: integer;
837+ sinA, cosA, x,y: double;
838+ begin
839+ SetLength(Result, length(path));
840+ SinCos(angle, sinA, cosA);
841+ for i := 0 to high(path) do
842+ begin
843+ x := path[i].X - focalPoint.X;
844+ y := path[i].Y - focalPoint.Y;
845+ Result[i].X := x * cosA - y * sinA + focalPoint.X;
846+ Result[i].Y := x * sinA + y * cosA + focalPoint.Y;
847+ end ;
835848end ;
836849
837- procedure Test_RectClip64 (edgeCnt: integer);
850+
851+ procedure Test_RectClipD (shapeCount: integer);
838852var
839853 i, sol2_len, rec_margin: Integer;
840- sub, clp, sol1, sol2: TPaths64 ;
841- csub_local: CPaths64 ;
842- csol_extern: CPaths64 ;
854+ sub, clp, sol1, sol2: TPathsD ;
855+ csub_local: CPathsD ;
856+ csol_extern: CPathsD ;
843857 penClr, fillClr: TColor32;
844- frac: Double;
845- rec: TRect64 ;
858+ scaleRnd, maxOffX, maxOffY, frac: Double;
859+ rec: TRectD ;
846860 fillrule: TFillRule;
847861 svg: TSvgWriter;
862+ shapes: array [0 ..3 ] of TPathD;
863+ const
864+ w = 300 ;
865+ h = 300 ;
848866begin
849- fillrule := frEvenOdd;
867+ // four simple concave polygons
868+ shapes[0 ] := MakePathD([20 ,20 , 20 ,0 , 40 ,0 , 40 ,20 , 60 ,20 , 60 ,40 ,
869+ 40 ,40 , 40 ,60 , 20 ,60 , 20 ,40 , 0 ,40 , 0 ,20 ]);
870+ shapes[1 ] := MakePathD([0 ,0 , 60 ,0 , 60 ,20 , 20 ,20 , 20 ,40 , 60 ,40 ,
871+ 60 ,60 , 0 ,60 ]);
872+ shapes[2 ] := MakePathD([0 ,0 , 20 ,0 , 20 ,20 , 40 ,20 , 40 ,0 , 60 ,0 ,
873+ 60 ,60 , 40 ,60 , 40 ,40 , 20 ,40 , 20 ,60 , 0 ,60 ]);
874+ shapes[3 ] := MakePathD([20 ,60 , 20 ,20 , 0 ,20 , 0 ,0 , 60 ,0 , 60 ,20 ,
875+ 40 ,20 , 40 ,60 ]);
876+
877+ fillrule := frNonZero;
850878
851879 // setup
852880 WriteLn(#10 ' Testing RectClip64:' );
853- SetLength(sub, 1 );
854-
855- sub[0 ] := MakeRandomPath(displayWidth, displayHeight, edgeCnt);
856- csub_local := TPaths64ToCPaths64(sub);
857881
858- rec_margin := displayHeight div 3 ;
882+ rec_margin := Min(w,h) div 3 ;
859883 rec.Left := rec_margin;
860884 rec.Top := rec_margin;
861- rec.Right := displayWidth - rec_margin;
862- rec.Bottom := displayHeight -rec_margin;
863-
864- // display 'sub' and 'rec' on the console
865- WriteLn(#10 ' subject:' );
866- WritePath64(sub[0 ]);
885+ rec.Right := w - rec_margin;
886+ rec.Bottom := h -rec_margin;
867887
868- // display 'rec' on the console
869- WriteLn(#10 ' rect path:' );
870- WritePath64(rec.AsPath);
888+ SetLength(sub, shapeCount);
889+ for i := 0 to shapeCount -1 do
890+ begin
891+ scaleRnd := (60 + Random(w div 4 )) / 120 ;
892+ maxOffX := w - (scaleRnd * 60 );
893+ maxOffY := h - (scaleRnd * 60 );
894+ sub[i] := ScalePathD(shapes[Random(4 )], scaleRnd);
895+ sub[i] := TranslatePath(sub[i],
896+ Random(Round(maxOffX)), Random(Round(maxOffY)));
897+ end ;
871898
872- // do the DLL operation (twice :))
873- csol_extern := RectClip64(rec, csub_local, true);
874- sol1 := CPaths64ToPaths64(csol_extern);
875- DisposeExportedCPaths64(csol_extern);
899+ // do the DLL operation with ConvexOnly enabled
900+ { $IFDEF USING_CLIPPER2_SRC}
901+ sol1 := RectClip( rec, sub, true, 2 );
902+ sol2 := RectClip( rec, sub, false, 2 );
903+ csub_local := nil ;
904+ csol_extern := nil ;
905+ { $ELSE}
906+ csub_local := TPathsDToCPathsD(sub);
907+ csol_extern := RectClipD(rec, csub_local, 2 , true);
908+ sol1 := CPathsDToPathsD(csol_extern);
909+ DisposeExportedCPathsD(csol_extern);
876910
877- csol_extern := RectClip64(rec, csub_local, false);
878- sol2 := CPaths64ToPaths64(csol_extern);
911+ // do the DLL operation again with ConvexOnly disabled
912+ csol_extern := RectClipD(rec, csub_local, 2 , false);
913+ sol2 := CPathsDToPathsD(csol_extern);
914+ { $ENDIF}
879915
880- // display result on the console
881- WriteLn(#10 ' solution:' );
882- WriteCPaths64(csol_extern);
883916
884917 // display and clean up
885-
886918 sol2_len := Length(sol2);
887919 if sol2_len = 0 then
888920 frac := 0 else
@@ -892,47 +924,35 @@ begin
892924 fillClr := (penClr and $FFFFFF) or $20000000 ;
893925
894926 SetLength(clp, 1 );
895- clp[0 ] := RectToPath64( rec) ;
927+ clp[0 ] := rec.AsPath ;
896928
897929 svg := TSvgWriter.Create(fillrule);
898930 try
899931 AddSubject(svg, sub);
900932 AddClip(svg, clp);
901933
902934 // display the unclipped paths
903- SaveSvg(svg, ' RectClip64_1.svg' , displayWidth, displayHeight );
935+ SaveSvg(svg, ' RectClip64_1.svg' , w, h );
904936 ShowSvgImage(' RectClip64_1.svg' );
905937
906- // display the first RectClip operation (ignores concavity )
938+ // display the first RectClip operation (assumes ConvexOnly )
907939 AddSolution(svg, sol1);
908- SaveSvg(svg, ' RectClip64_2.svg' , displayWidth, displayHeight );
940+ SaveSvg(svg, ' RectClip64_2.svg' , w, h );
909941 ShowSvgImage(' RectClip64_2.svg' );
910942
911943 svg.ClearPaths;
912944 // display the second RectClip operation (manages convexity)
913945 AddSubject(svg, sub);
914946 AddClip(svg, clp);
915947 AddSolution(svg, sol2);
916- SaveSvg(svg, ' RectClip64_3.svg' , displayWidth, displayHeight );
948+ SaveSvg(svg, ' RectClip64_3.svg' , w, h );
917949 ShowSvgImage(' RectClip64_3.svg' );
918-
919- svg.ClearPaths;
920- // display the second RectClip operation (manages convexity)
921- // but this time showing solutions with multi-colored paths
922- AddSubject(svg, sub);
923- AddClip(svg, clp);
924- for i := 0 to sol2_len -1 do
925- svg.AddPath(sol2[i], false, fillClr, penClr, 1.5 , false);
926-
927- SaveSvg(svg, ' RectClip64_4.svg' , displayWidth, displayHeight);
928- ShowSvgImage(' RectClip64_4.svg' );
929-
930950 finally
931951 svg.Free;
932952 end ;
933953
934- DisposeLocalCPaths64 (csub_local);
935- DisposeExportedCPaths64 (csol_extern);
954+ DisposeLocalCPathsD (csub_local);
955+ DisposeExportedCPathsD (csol_extern);
936956end ;
937957
938958procedure Test_RectClipLines64 (edgeCnt: integer);
@@ -964,7 +984,7 @@ begin
964984 // finally, display and clean up
965985
966986 SetLength(clp, 1 );
967- clp[0 ] := RectToPath64( rec) ;
987+ clp[0 ] := rec.AsPath ;
968988
969989 svg := TSvgWriter.Create(frNonZero);
970990 try
9891009 csub_local, cclp_local: CPaths64;
9901010 csol_extern, csolo_extern: CPaths64;
9911011 svg: TSvgWriter;
1012+ const
1013+ w = 800 ;
1014+ h = 600 ;
9921015begin
9931016 csolo_extern := nil ;
9941017 WriteLn(#10 ' Testing Performance' );
@@ -997,9 +1020,9 @@ begin
9971020 Write(format(#10 ' C++ DLL - %d edges: ' , [i*1000 ]));
9981021 // setup
9991022 SetLength(sub, 1 );
1000- sub[0 ] := MakeRandomPath(displayWidth, displayHeight , i*1000 );
1023+ sub[0 ] := MakeRandomPath(w, h , i*1000 );
10011024 SetLength(clp, 1 );
1002- clp[0 ] := MakeRandomPath(displayWidth, displayHeight , i*1000 );
1025+ clp[0 ] := MakeRandomPath(w, h , i*1000 );
10031026 // convert paths into DLL structures (will require local clean up)
10041027 csub_local := TPaths64ToCPaths64(sub);
10051028 cclp_local := TPaths64ToCPaths64(clp);
@@ -1031,7 +1054,7 @@ begin
10311054 AddSubject(svg, sub);
10321055 AddClip(svg, clp);
10331056 AddSolution(svg, CPaths64ToPaths64(csol_extern));
1034- SaveSvg(svg, ' Performance.svg' , displayWidth, displayHeight );
1057+ SaveSvg(svg, ' Performance.svg' , w, h );
10351058 ShowSvgImage(' Performance.svg' );
10361059 finally
10371060 svg.Free;
@@ -1059,11 +1082,11 @@ begin
10591082// Test_BooleanOp64(50);
10601083// Test_BooleanOpD(75);
10611084// Test_BooleanOpPtD(20);
1062- // Test_InflatePaths64( -10);
1063- Test_RectClip64( 25 );
1085+ Test_InflatePathsD( 20 , -10 ); // edgeCount, offsetDist
1086+ // Test_RectClipD(15 );
10641087// Test_RectClipLines64(25);
1065- // Test_Performance(1, 5); // 1000 t0 5000
1066- // Test_MegaStress(10000);
1088+ // Test_Performance(1, 5); // 1000 to 5000
1089+ // Test_MegaStress(10000);
10671090
10681091 WriteLn(#10 ' Press Enter to quit.' );
10691092 ReadLn(s);
0 commit comments