From 1928a1812bb296bb3fd09b9a0084e30048332fa6 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Thu, 23 Nov 2023 09:15:38 +0100 Subject: [PATCH] Ellipse: check at 7*7 points --- Base/Axis/Bin.cpp | 5 +++++ Base/Axis/Bin.h | 1 + Device/Mask/Ellipse.cpp | 15 ++++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Base/Axis/Bin.cpp b/Base/Axis/Bin.cpp index c6461fcbf14..d731b4a9000 100644 --- a/Base/Axis/Bin.cpp +++ b/Base/Axis/Bin.cpp @@ -43,6 +43,11 @@ Bin1D::Bin1D(double lower, double upper) } } +double Bin1D::atFraction(double fraction) const +{ + return m_lower * (1 - fraction) + m_upper * fraction; +} + std::optional<Bin1D> Bin1D::clipped_or_nil(double lower, double upper) const { ASSERT(lower <= upper); diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h index 0efd1201f01..6651b02fffb 100644 --- a/Base/Axis/Bin.h +++ b/Base/Axis/Bin.h @@ -33,6 +33,7 @@ public: double upperBound() const { return m_upper; } double center() const { return (m_lower + m_upper) / 2; } double binSize() const { return m_upper - m_lower; } + double atFraction(double fraction) const; std::optional<Bin1D> clipped_or_nil(double lower, double upper) const; diff --git a/Device/Mask/Ellipse.cpp b/Device/Mask/Ellipse.cpp index 13ea40d4392..c9d38dac4b8 100644 --- a/Device/Mask/Ellipse.cpp +++ b/Device/Mask/Ellipse.cpp @@ -37,17 +37,22 @@ Ellipse::Ellipse(double xcenter, double ycenter, double xradius, double yradius, bool Ellipse::contains(double x, double y) const { - double u = std::cos(m_theta) * (x - m_xc) + std::sin(m_theta) * (y - m_yc); - double v = -std::sin(m_theta) * (x - m_xc) + std::cos(m_theta) * (y - m_yc); + double u = std::cos(m_theta) * (x - m_xc) - std::sin(m_theta) * (y - m_yc); + double v = std::sin(m_theta) * (x - m_xc) + std::cos(m_theta) * (y - m_yc); double d = (u / m_xr) * (u / m_xr) + (v / m_yr) * (v / m_yr); return d <= 1; } -//! Returns true if area defined by two bins is inside or on border of ellipse; -//! more precisely, if mid point of two bins satisfy this condition. bool Ellipse::contains(const Bin1D& binx, const Bin1D& biny) const { - return contains(binx.center(), biny.center()); + // The overlap of an ellipse and a rectangle, in full generality, requires quite + // a complicated algorithm. We therefore content ourselves with a check for n*n points. + const int n = 7; + for (int ix = 0; ix < n; ++ix) + for (int iy = 0; iy < n; ++iy) + if (contains(binx.atFraction(ix / (n - 1.)), biny.atFraction(iy / (n - 1.)))) + return true; + return false; } void Ellipse::print(std::ostream& ostr) const -- GitLab