From 562ef2da53e9eddeb638c3f79944aa293b84a0cc Mon Sep 17 00:00:00 2001 From: angusj Date: Mon, 17 Jul 2023 18:58:41 +1000 Subject: [PATCH] Another minor bugfix in GetIntersectPoint(). (#568) And a minor code tidy. --- .../include/clipper2/clipper.core.h | 2 +- CSharp/Clipper2Lib/Clipper.Core.cs | 18 ++--- CSharp/Clipper2Lib/Clipper2Lib.csproj | 8 -- CSharp/USINGZ.TestApp/Program.cs | 79 +++++++++++++++++++ CSharp/USINGZ.TestApp/UsingZTestApp.csproj | 23 ++++++ CSharp/USINGZ.TestApp/UsingZ_TestApp.sln | 31 ++++++++ CSharp/USINGZ/Clipper2LibZ.csproj | 8 ++ Delphi/Clipper2Lib/Clipper.Core.pas | 4 +- Delphi/Clipper2Lib/Clipper.pas | 9 ++- 9 files changed, 160 insertions(+), 22 deletions(-) create mode 100644 CSharp/USINGZ.TestApp/Program.cs create mode 100644 CSharp/USINGZ.TestApp/UsingZTestApp.csproj create mode 100644 CSharp/USINGZ.TestApp/UsingZ_TestApp.sln diff --git a/CPP/Clipper2Lib/include/clipper2/clipper.core.h b/CPP/Clipper2Lib/include/clipper2/clipper.core.h index 171488f0..bdcb702a 100644 --- a/CPP/Clipper2Lib/include/clipper2/clipper.core.h +++ b/CPP/Clipper2Lib/include/clipper2/clipper.core.h @@ -693,7 +693,7 @@ namespace Clipper2Lib if (det == 0.0) return false; double t = ((ln1a.x - ln2a.x) * dy2 - (ln1a.y - ln2a.y) * dx2) / det; if (t <= 0.0) ip = ln1a; // ?? check further (see also #568) - else if (t >= 1.0) ip = ln2a; // ?? check further + else if (t >= 1.0) ip = ln1b; // ?? check further else { ip.x = static_cast(ln1a.x + t * dx1); diff --git a/CSharp/Clipper2Lib/Clipper.Core.cs b/CSharp/Clipper2Lib/Clipper.Core.cs index 4f526677..6ab1de6a 100644 --- a/CSharp/Clipper2Lib/Clipper.Core.cs +++ b/CSharp/Clipper2Lib/Clipper.Core.cs @@ -1,6 +1,6 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 16 July 2023 * +* Date : 17 July 2023 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2023 * * Purpose : Core structures and functions for the Clipper Library * @@ -631,18 +631,18 @@ internal static bool GetIntersectPt(Point64 ln1a, double dx1 = (ln1b.X - ln1a.X); double dy2 = (ln2b.Y - ln2a.Y); double dx2 = (ln2b.X - ln2a.X); - double cp = dy1 * dx2 - dy2 * dx1; - if (cp == 0.0) + double det = dy1 * dx2 - dy2 * dx1; + if (det == 0.0) { ip = new Point64(); return false; } - double qx = dx1 * ln1a.Y - dy1 * ln1a.X; - double qy = dx2 * ln2a.Y - dy2 * ln2a.X; - ip = new Point64( - CheckCastInt64((dx1 * qy - dx2 * qx) / cp), - CheckCastInt64((dy1 * qy - dy2 * qx) / cp)); - return (ip.X != Invalid64 && ip.Y != Invalid64); + + double t = ((ln1a.X - ln2a.X) * dy2 - (ln1a.Y - ln2a.Y) * dx2) / det; + if (t <= 0.0) ip = ln1a; + else if (t >= 1.0) ip = ln1b; + else ip = new Point64(ln1a.X + t * dx1, ln1a.Y + t * dy1); + return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/CSharp/Clipper2Lib/Clipper2Lib.csproj b/CSharp/Clipper2Lib/Clipper2Lib.csproj index 505c1e8a..93e544b2 100644 --- a/CSharp/Clipper2Lib/Clipper2Lib.csproj +++ b/CSharp/Clipper2Lib/Clipper2Lib.csproj @@ -25,12 +25,4 @@ TRACE - - - - - - - - diff --git a/CSharp/USINGZ.TestApp/Program.cs b/CSharp/USINGZ.TestApp/Program.cs new file mode 100644 index 00000000..4d290bd7 --- /dev/null +++ b/CSharp/USINGZ.TestApp/Program.cs @@ -0,0 +1,79 @@ +/******************************************************************************* +* Author : Angus Johnson * +* Date : 24 January 2023 * +* Website : http://www.angusj.com * +* Copyright : Angus Johnson 2010-2023 * +* License : http://www.boost.org/LICENSE_1_0.txt * +*******************************************************************************/ + +using System.Collections.Generic; +using System.Reflection; +using System.IO; +using System; +using System.Security.Cryptography; +using System.Xml.Linq; +using System.Runtime.InteropServices; +using System.Diagnostics; + +using Clipper2Lib; + +public class Application +{ + public class MyCallbacks + { + public void MyCallback64(Point64 bot1, Point64 top1, + Point64 bot2, Point64 top2, ref Point64 intersectPt) + { + intersectPt.Z = 1; + } + + public void MyCallbackD(PointD bot1, PointD top1, + PointD bot2, PointD top2, ref PointD intersectPt) + { + intersectPt.z = 1; + } + } + + public static void Main() + { + PathsD solution = new PathsD(); + PathsD subject = new PathsD(); + subject.Add(Clipper.MakePath(new double[] { 100, 50, 10, 79, 65, 2, 65, 98, 10, 21 })); + + ClipperD clipperD = new ClipperD(); + MyCallbacks cb = new MyCallbacks(); + clipperD.ZCallback = cb.MyCallbackD; + clipperD.AddSubject(subject); + clipperD.Execute(ClipType.Union, FillRule.NonZero, solution); + + + Console.WriteLine(solution.ToString(0)); + + SvgWriter svg= new SvgWriter(FillRule.NonZero); + SvgUtils.AddSubject(svg, subject); + SvgUtils.AddSolution(svg, solution, false); + + PathsD ellipses = new PathsD(); + for (int i = 0; i < solution[0].Count; i++) + { + if (solution[0][i].z == 1) + ellipses.Add(Clipper.Ellipse( + new PointD(solution[0][i].x, solution[0][i].y), 4)); + } + svg.AddClosedPaths(ellipses, 0x20FF0000, 0xFFFF0000, 1); + svg.SaveToFile("usingz.svg", 300, 300); + OpenFileWithDefaultApp("usingz.svg"); + } + + public static void OpenFileWithDefaultApp(string filename) + { + string path = Path.GetFullPath(filename); + if (!File.Exists(path)) return; + Process p = new Process() + { + StartInfo = new ProcessStartInfo(path) { UseShellExecute = true } + }; + p.Start(); + } + +} diff --git a/CSharp/USINGZ.TestApp/UsingZTestApp.csproj b/CSharp/USINGZ.TestApp/UsingZTestApp.csproj new file mode 100644 index 00000000..11464c72 --- /dev/null +++ b/CSharp/USINGZ.TestApp/UsingZTestApp.csproj @@ -0,0 +1,23 @@ + + + + Exe + net6.0 + enable + enable + + + + $(DefineConstants);USINGZ + + + + + + + + + + + + diff --git a/CSharp/USINGZ.TestApp/UsingZ_TestApp.sln b/CSharp/USINGZ.TestApp/UsingZ_TestApp.sln new file mode 100644 index 00000000..2bac2abb --- /dev/null +++ b/CSharp/USINGZ.TestApp/UsingZ_TestApp.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33205.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UsingZTestApp", "UsingZTestApp.csproj", "{34A93225-8048-4A5A-8741-BC619C13C7B0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clipper2LibZ", "..\USINGZ\Clipper2LibZ.csproj", "{C50EB9B5-CE07-49DE-B147-941DBFB4FA4E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {34A93225-8048-4A5A-8741-BC619C13C7B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34A93225-8048-4A5A-8741-BC619C13C7B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34A93225-8048-4A5A-8741-BC619C13C7B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34A93225-8048-4A5A-8741-BC619C13C7B0}.Release|Any CPU.Build.0 = Release|Any CPU + {C50EB9B5-CE07-49DE-B147-941DBFB4FA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C50EB9B5-CE07-49DE-B147-941DBFB4FA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C50EB9B5-CE07-49DE-B147-941DBFB4FA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C50EB9B5-CE07-49DE-B147-941DBFB4FA4E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0E1221D6-32D4-4974-9205-DE97EC5F4937} + EndGlobalSection +EndGlobal diff --git a/CSharp/USINGZ/Clipper2LibZ.csproj b/CSharp/USINGZ/Clipper2LibZ.csproj index f9b0fb7e..15fa9407 100644 --- a/CSharp/USINGZ/Clipper2LibZ.csproj +++ b/CSharp/USINGZ/Clipper2LibZ.csproj @@ -14,4 +14,12 @@ TRACE;DEBUG;USINGZ; + + + + + + + + diff --git a/Delphi/Clipper2Lib/Clipper.Core.pas b/Delphi/Clipper2Lib/Clipper.Core.pas index 4bf5f9b3..4e710bd8 100644 --- a/Delphi/Clipper2Lib/Clipper.Core.pas +++ b/Delphi/Clipper2Lib/Clipper.Core.pas @@ -2,7 +2,7 @@ (******************************************************************************* * Author : Angus Johnson * -* Date : 16 July 2023 * +* Date : 17 July 2023 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2023 * * Purpose : Core Clipper Library module * @@ -1949,7 +1949,7 @@ function GetIntersectPoint(const ln1a, ln1b, ln2a, ln2b: TPoint64; if not Result then Exit; t := ((ln1a.x-ln2a.x) * dy2 - (ln1a.y-ln2a.y) * dx2) / cp; if t <= 0.0 then ip := ln1a - else if t >= 1.0 then ip := ln2a; + else if t >= 1.0 then ip := ln1b; ip.X := Trunc(ln1a.X + t * dx1); ip.Y := Trunc(ln1a.Y + t * dy1); end; diff --git a/Delphi/Clipper2Lib/Clipper.pas b/Delphi/Clipper2Lib/Clipper.pas index 4fc8d203..73fb3260 100644 --- a/Delphi/Clipper2Lib/Clipper.pas +++ b/Delphi/Clipper2Lib/Clipper.pas @@ -2,7 +2,7 @@ (******************************************************************************* * Author : Angus Johnson * -* Date : 16 July 2023 * +* Date : 17 July 2023 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2023 * * Purpose : This module provides a simple interface to the Clipper Library * @@ -814,8 +814,13 @@ function PointInPolygon(const pt: TPoint64; function DistanceSqrd(const pt1, pt2: TPoint64): double; {$IFDEF INLINE} inline; {$ENDIF} +var + x1,y1,x2,y2: double; begin - result := Sqr(double(pt1.X) - pt2.X) + Sqr(double(pt1.Y) - pt2.Y); + // nb: older versions of Delphi don't allow explicit typcasting + x1 := pt1.X; y1 := pt1.Y; + x2 := pt2.X; y2 := pt2.Y; + result := Sqr(x1 - x2) + Sqr(y1 - y2); end; //------------------------------------------------------------------------------