Skip to content

Commit

Permalink
Minor code tidies
Browse files Browse the repository at this point in the history
  • Loading branch information
AngusJohnson committed May 11, 2024
1 parent 6e4feb8 commit 2b9b7ce
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 28 deletions.
32 changes: 17 additions & 15 deletions CPP/Clipper2Lib/include/clipper2/clipper.core.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 7 May 2024 *
* Date : 11 May 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : Core Clipper Library structures and functions *
Expand Down Expand Up @@ -664,17 +664,19 @@ namespace Clipper2Lib
return (x > 0) - (x < 0);
}

inline uint64_t CalculateCarry(uint64_t a, uint64_t b)
inline uint64_t CalcOverflowCarry(uint64_t a, uint64_t b)
{
// adapted from: https://stackoverflow.com/a/1815391/19254
const uint64_t a0 = a & ((1ull << 32) - 1);
const uint64_t a1 = a >> 32;
const uint64_t b0 = b & ((1ull << 32) - 1);
const uint64_t b1 = b >> 32;
const uint64_t d11 = a1 * b0 + (a0 * b0 >> 32);
const uint64_t d12 = a0 * b1;
const uint64_t c1 = (d11 > (std::numeric_limits<uint64_t>::max)() - d12) ? 1 : 0;
return a1 * b1 + c1;
const uint64_t aHi = a & 0xFFFFFFFF00000000;
const uint64_t aLo = a & 0xFFFFFFFF;
const uint64_t bHi = b & 0xFFFFFFFF00000000;
const uint64_t bLo = b & 0xFFFFFFFF;
// a * b == (aHi + aLo) * (bHi + bLo)
// a * b == (aHi * bHi) + (aHi * bLo) + (aLo * bHi) + (aLo * bLo)
uint64_t carry = (aHi >> 32) * (bHi >> 32);
// but since (aHi * bLo) + (aLo * bHi) + (aLo * bLo) may also (just) overflow
// do safely ... if ((aHi * bLo) + (aLo * bHi) + (aLo * bLo) > MAX_UINT64) ++carry
if ((aLo * bHi) + (aLo * bLo) > ((std::numeric_limits<uint64_t>::max)() - (aHi * bLo))) ++carry;
return carry;
}

// returns true if (and only if) a * b == c * d
Expand All @@ -685,16 +687,16 @@ namespace Clipper2Lib
const auto abs_c = static_cast<uint64_t>(std::abs(c));
const auto abs_d = static_cast<uint64_t>(std::abs(d));

// NB: the multiplication here may potentially wrap
// the multiplications here can potentially overflow
// but any overflows will be compared further below.
const auto abs_ab = abs_a * abs_b;
const auto abs_cd = abs_c * abs_d;

const auto sign_ab = Sign(a) * Sign(b);
const auto sign_cd = Sign(c) * Sign(d);

const auto carry_ab = CalculateCarry(abs_a, abs_b);
const auto carry_cd = CalculateCarry(abs_c, abs_d);

const auto carry_ab = CalcOverflowCarry(abs_a, abs_b);
const auto carry_cd = CalcOverflowCarry(abs_c, abs_d);
return abs_ab == abs_cd && sign_ab == sign_cd && carry_ab == carry_cd;
}

Expand Down
21 changes: 11 additions & 10 deletions CSharp/Clipper2Lib/Clipper.Core.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 27 April 2024 *
* Date : 10 May 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : Core structures and functions for the Clipper Library *
Expand Down Expand Up @@ -480,7 +480,8 @@ public override string ToString()
{
string s = "";
foreach (Point64 p in this)
s = s + p.ToString() + " ";
s = s + p.ToString() + ", ";
if (s != "") s = s.Remove(s.Length - 2);
return s;
}
}
Expand Down Expand Up @@ -509,6 +510,7 @@ public string ToString(int precision = 2)
string s = "";
foreach (PointD p in this)
s = s + p.ToString(precision) + ", ";
if (s != "") s = s.Remove(s.Length - 2);
return s;
}
}
Expand Down Expand Up @@ -577,6 +579,13 @@ public static class InternalClipper
private static readonly string
precision_range_error = "Error: Precision is out of range.";

public static double CrossProduct(Point64 pt1, Point64 pt2, Point64 pt3)
{
// typecast to double to avoid potential int overflow
return ((double) (pt2.X - pt1.X) * (pt3.Y - pt2.Y) -
(double) (pt2.Y - pt1.Y) * (pt3.X - pt2.X));
}

#if USINGZ
public static Path64 SetZ(Path64 path, long Z)
{
Expand All @@ -597,14 +606,6 @@ internal static bool IsAlmostZero(double value)
return (Math.Abs(value) <= floatingPointTolerance);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static double CrossProduct(Point64 pt1, Point64 pt2, Point64 pt3)
{
// typecast to double to avoid potential int overflow
return ((double) (pt2.X - pt1.X) * (pt3.Y - pt2.Y) -
(double) (pt2.Y - pt1.Y) * (pt3.X - pt2.X));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsCollinear(Point64 pt1, Point64 pt2, Point64 pt3)
{
Expand Down
48 changes: 45 additions & 3 deletions CSharp/Clipper2Lib/Clipper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 27 April 2024 *
* Date : 10 May 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : This module contains simple functions that will likely cover *
Expand Down Expand Up @@ -654,9 +654,51 @@ public static PathD MakePathZ(double[] arr)


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Sqr(double value)
public static double Sqr(double val)
{
return value * value;
return val * val;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Sqr(long val)
{
return (double) val * (double) val;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double DistanceSqr(Point64 pt1, Point64 pt2)
{
return Sqr(pt1.X - pt2.X) + Sqr(pt1.Y - pt2.Y);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Point64 MidPoint(Point64 pt1, Point64 pt2)
{
return new Point64((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static PointD MidPoint(PointD pt1, PointD pt2)
{
return new PointD((pt1.x + pt2.x) / 2, (pt1.y + pt2.y) / 2);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InflateRect(ref Rect64 rec, int dx, int dy)
{
rec.left -= dx;
rec.right += dx;
rec.top -= dy;
rec.bottom += dy;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InflateRect(ref RectD rec, double dx, double dy)
{
rec.left -= dx;
rec.right += dx;
rec.top -= dy;
rec.bottom += dy;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down

0 comments on commit 2b9b7ce

Please sign in to comment.