[{"id":29395,"web_url":"https://patchwork.libcamera.org/comment/29395/","msgid":"<20240502191856.eofrpevgkgx7j54c@jasper>","date":"2024-05-02T19:18:56","subject":"Re: [PATCH v2 1/4] libcamera: geometry: Add floating-point version\n\tof Point class","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Paul,\n\nthanks for the patch.\n\nOn Fri, Apr 26, 2024 at 04:36:09PM +0900, Paul Elder wrote:\n> The piecewise linear function (Pwl) class from the Raspberry Pi IPA has\n> its own Point class while one already exists in libcamera's geometry.h\n> header. The reason is because libcamera's Point is on the plane of\n> integer, while Raspberry Pi's is on the plane of reals.\n\nnit: s/integer/integers/\n\n> \n> While making this a template class might be cleaner, it was deemed to be\n> too intrusive of a change, and it might not feel nice to need to specify\n> the type from a public API point of view. Hence we introduce a FPoint\n\nnit: s/FPoint/PointF/\n\n> class to designate a Point class on the plane of reals.\n> \n> This is in preparation for copying/moving the Pwl class from the\n> Raspberry Pi IPA to libipa.\n> \n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> ---\n> Changes in v2:\n> - renamed FPoint to PointF\n> - add documentation\n> - add tests\n> ---\n>  include/libcamera/geometry.h |  65 +++++++\n>  src/libcamera/geometry.cpp   | 123 +++++++++++-\n>  test/geometry.cpp            | 355 +++++++++++++++++++++++++++++++++++\n>  3 files changed, 542 insertions(+), 1 deletion(-)\n> \n> diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n> index d7fdbe70..6aef1f39 100644\n> --- a/include/libcamera/geometry.h\n> +++ b/include/libcamera/geometry.h\n> @@ -8,6 +8,7 @@\n>  #pragma once\n>  \n>  #include <algorithm>\n> +#include <cmath>\n>  #include <ostream>\n>  #include <string>\n>  \n> @@ -49,6 +50,70 @@ static inline bool operator!=(const Point &lhs, const Point &rhs)\n>  \n>  std::ostream &operator<<(std::ostream &out, const Point &p);\n>  \n> +struct PointF {\n> +\tconstexpr PointF()\n> +\t\t: x(0), y(0)\n> +\t{\n> +\t}\n> +\n> +\tconstexpr PointF(double _x, double _y)\n> +\t\t: x(_x), y(_y)\n> +\t{\n> +\t}\n> +\n> +\tconstexpr PointF operator-() const\n> +\t{\n> +\t\treturn PointF{ -x, -y };\n> +\t}\n> +\n> +\tconstexpr PointF operator-(const PointF &p) const\n> +\t{\n> +\t\treturn PointF(x - p.x, y - p.y);\n> +\t}\n> +\n> +\tconstexpr PointF operator+(const PointF &p) const\n> +\t{\n> +\t\treturn PointF(x + p.x, y + p.y);\n> +\t}\n> +\n> +\tconstexpr double operator%(const PointF &p) const\n> +\t{\n> +\t\treturn x * p.x + y * p.y;\n> +\t}\n\nThis operator implementation is unexpected to me. Is that a common usage\nfor % ? I would need to look that up, whilst a dot() function would\nconvey the intend immediately (at least to me).\n\nWith or without that changed:\nReviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> \n\nCheers,\nStefan\n\n> +\n> +\tconstexpr PointF operator*(double f) const\n> +\t{\n> +\t\treturn PointF(x * f, y * f);\n> +\t}\n> +\n> +\tconstexpr PointF operator/(double f) const\n> +\t{\n> +\t\treturn PointF(x / f, y / f);\n> +\t}\n> +\n> +\tconstexpr double len2() const\n> +\t{\n> +\t\treturn x * x + y * y;\n> +\t}\n> +\n> +\tconstexpr double len() const\n> +\t{\n> +\t\treturn std::sqrt(len2());\n> +\t}\n> +\n> +\tconst std::string toString() const;\n> +\n> +\tdouble x, y;\n> +};\n> +\n> +bool operator==(const PointF &lhs, const PointF &rhs);\n> +static inline bool operator!=(const PointF &lhs, const PointF &rhs)\n> +{\n> +\treturn !(lhs == rhs);\n> +}\n> +\n> +std::ostream &operator<<(std::ostream &out, const PointF &p);\n> +\n>  class Size\n>  {\n>  public:\n> diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp\n> index 8d85b758..90b81282 100644\n> --- a/src/libcamera/geometry.cpp\n> +++ b/src/libcamera/geometry.cpp\n> @@ -21,7 +21,7 @@ namespace libcamera {\n>  \n>  /**\n>   * \\class Point\n> - * \\brief Describe a point in two-dimensional space\n> + * \\brief Describe a point in two-dimensional integer space\n>   *\n>   * The Point structure defines a point in two-dimensional space with integer\n>   * precision. The coordinates of a Point may be negative as well as positive.\n> @@ -94,6 +94,127 @@ std::ostream &operator<<(std::ostream &out, const Point &p)\n>  \treturn out;\n>  }\n>  \n> +/**\n> + * \\class PointF\n> + * \\brief Describe a point in two-dimensional real space\n> + *\n> + * The Point structure defines a point in two-dimensional space with double\n> + * precision. The coordinates of a Point may be negative as well as positive.\n> + *\n> + * This class exists separately from Point to not require all users of the\n> + * Point class to have to use template parameters to specify a type.\n> + */\n> +\n> +/**\n> + * \\fn PointF::PointF()\n> + * \\copydoc libcamera::Point::Point\n> + */\n> +\n> +/**\n> + * \\fn PointF::PointF(double _x, double _y)\n> + * \\brief Construct a PointF at given \\a _x and \\a _y values\n> + * \\param[in] _x The x-coordinate\n> + * \\param[in] _y The y-coordinate\n> + */\n> +\n> +/**\n> + * \\var PointF::x\n> + * \\copydoc libcamera::Point::x\n> + */\n> +\n> +/**\n> + * \\var PointF::y\n> + * \\copydoc libcamera::Point::y\n> + */\n> +\n> +/**\n> + * \\fn constexpr PointF PointF::operator-() const\n> + * \\copydoc libcamera::Point::operator-\n> + */\n> +\n> +/**\n> + * \\fn constexpr PointF PointF::operator-(PointF const &p) const\n> + * \\brief Subtract one point from another, as if they were vectors\n> + * \\param[in] p The other point\n> + * \\return The difference of p from this point\n> + */\n> +\n> +/**\n> + * \\fn PointF::operator+()\n> + * \\brief Add two points together, as if they were vectors\n> + * \\param[in] p The other point\n> + * \\return The sum of the two points\n> + */\n> +\n> +/**\n> + * \\fn PointF::operator%()\n> + * \\brief Compute the dot product, treating the points as vectors\n> + * \\param[in] p The other point\n> + * \\return The dot product of the two points\n> + */\n> +\n> +/**\n> + * \\fn PointF::operator*()\n> + * \\brief Scale up the point, as if it were a vector\n> + * \\param[in] f The factor\n> + * \\return The scaled point\n> + */\n> +\n> +/**\n> + * \\fn PointF::operator/()\n> + * \\brief Scale down the point, as if it were a vector\n> + * \\param[in] f The factor\n> + * \\return The scaled point\n> + */\n> +\n> +/**\n> + * \\fn PointF::len2()\n> + * \\brief Get the squared length of the point, as if it were a vector\n> + * \\return The squared length of the point\n> + */\n> +\n> +/**\n> + * \\fn PointF::len()\n> + * \\brief Get the length of the point, as if it were a vector\n> + * \\return The length of the point\n> + */\n> +\n> +/**\n> + * \\copydoc Point::toString()\n> + */\n> +const std::string PointF::toString() const\n> +{\n> +\tstd::stringstream ss;\n> +\tss << *this;\n> +\n> +\treturn ss.str();\n> +}\n> +\n> +/**\n> + * \\copydoc operator==(const Point &lhs, const Point &rhs)\n> + */\n> +bool operator==(const PointF &lhs, const PointF &rhs)\n> +{\n> +\treturn lhs.x == rhs.x && lhs.y == rhs.y;\n> +}\n> +\n> +/**\n> + * \\fn bool operator!=(const Point &lhs, const Point &rhs)\n> + * \\copydoc libcamera::Point::operator!=\n> + */\n> +\n> +/**\n> + * \\brief Insert a text representation of a PointF into an output stream\n> + * \\param[in] out The output stream\n> + * \\param[in] p The point\n> + * \\return The output stream \\a out\n> + */\n> +std::ostream &operator<<(std::ostream &out, const PointF &p)\n> +{\n> +\tout << \"(\" << p.x << \", \" << p.y << \")\";\n> +\treturn out;\n> +}\n> +\n>  /**\n>   * \\class Size\n>   * \\brief Describe a two-dimensional size\n> diff --git a/test/geometry.cpp b/test/geometry.cpp\n> index 008d51ea..7f1f5b1a 100644\n> --- a/test/geometry.cpp\n> +++ b/test/geometry.cpp\n> @@ -33,6 +33,53 @@ protected:\n>  \t\treturn true;\n>  \t}\n>  \n> +\ttemplate<typename T, typename U, typename V>\n> +\tbool compareF(const T &lhs, const U &rhs,\n> +\t\t      V (PointF::*op)(const U &) const,\n> +\t\t      const char *opName, V expect)\n> +\t{\n> +\t\tV result = (lhs.*op)(rhs);\n> +\n> +\t\tif (result != expect) {\n> +\t\t\tcout << lhs << opName << \" \" << rhs\n> +\t\t\t     << \"test failed\" << std::endl;\n> +\t\t\treturn false;\n> +\t\t}\n> +\n> +\t\treturn true;\n> +\t}\n> +\n> +\ttemplate<typename T, typename U, typename V>\n> +\tbool compareFScale(const T &lhs, const U &rhs,\n> +\t\t\t   V (PointF::*op)(U) const,\n> +\t\t\t   const char *opName, V expect)\n> +\t{\n> +\t\tV result = (lhs.*op)(rhs);\n> +\n> +\t\tif (result != expect) {\n> +\t\t\tcout << lhs << opName << \" \" << rhs\n> +\t\t\t     << \"test failed\" << std::endl;\n> +\t\t\treturn false;\n> +\t\t}\n> +\n> +\t\treturn true;\n> +\t}\n> +\n> +\ttemplate<typename T>\n> +\tbool compareFLen(const T &lhs, double (PointF::*op)() const,\n> +\t\t\t const char *opName, double expect)\n> +\t{\n> +\t\tdouble result = (lhs.*op)();\n> +\n> +\t\tif (result != expect) {\n> +\t\t\tcout << lhs << opName\n> +\t\t\t     << \"test failed\" << std::endl;\n> +\t\t\treturn false;\n> +\t\t}\n> +\n> +\t\treturn true;\n> +\t}\n> +\n>  \tint run()\n>  \t{\n>  \t\t/*\n> @@ -88,6 +135,314 @@ protected:\n>  \t\t\treturn TestFail;\n>  \t\t}\n>  \n> +\t\t/*\n> +\t\t * PointF tests\n> +\t\t */\n> +\n> +\t\t/* Equality */\n> +\t\tif (!compare(PointF(50.1, 100.1), PointF(50.1, 100.1), &operator==, \"==\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, 100.1), PointF(-50.1, 100.1), &operator==, \"==\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(50.1, -100.1), PointF(50.1, -100.1), &operator==, \"==\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, -100.1), PointF(-50.1, -100.1), &operator==, \"==\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, -100.0), PointF(-50.1, -100), &operator==, \"==\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Inequality */\n> +\t\tif (!compare(PointF(50.1, 100.1), PointF(50.1, 100.2), &operator!=, \"!=\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, 100.1), PointF(-50.1, 100.01), &operator!=, \"!=\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, 100.1), PointF(-50.1, 100.1), &operator!=, \"!=\", false))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(50.1, -100.1), PointF(50.2, -100.1), &operator!=, \"!=\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, -100.1), PointF(-50.01, -100.0), &operator!=, \"!=\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, 100.1), PointF(50.1, 100.1), &operator!=, \"!=\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(50.1, -100.1), PointF(50.1, 100.1), &operator!=, \"!=\", true))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compare(PointF(-50.1, -100.1), PointF(-50.1, -100.1), &operator!=, \"!=\", false))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Negation */\n> +\t\tif (PointF(50.1, 100.1) != -PointF(-50.1, -100.1) ||\n> +\t\t    PointF(50.1, 100.1) == -PointF(50.1, -100.1) ||\n> +\t\t    PointF(50.1, 100.1) == -PointF(-50.1, 100.1)) {\n> +\t\t\tcout << \"PointF negation test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\ttypedef PointF (PointF::*pointfOp)(const PointF &) const;\n> +\t\ttypedef double (PointF::*pointfDotProd)(const PointF &) const;\n> +\t\ttypedef PointF (PointF::*pointfScale)(double) const;\n> +\t\ttypedef double (PointF::*pointfLen)() const;\n> +\n> +\t\t/* Subtraction */\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(0, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(-50.1, 100.1), PointF(-50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(0, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, -100.1), PointF(50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(0, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(-50.1, -100.1), PointF(-50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(0, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(-50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(100.2, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(0, 200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(-50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(100.2, 200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(-50.1, 100.1), PointF(50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator-), \"-\",\n> +\t\t\t      PointF(-100.2, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Addition */\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(100.2, 200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(-50.1, 100.1), PointF(-50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(-100.2, 200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, -100.1), PointF(50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(100.2, -200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(-50.1, -100), PointF(-50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(-100.2, -200.1)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(-50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(0, 200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.0), PointF(50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(100.2, -0.09999999999999432)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(50.1, 100.1), PointF(-50.1, -100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(0, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, PointF>(PointF(-50.1, 100.1), PointF(50.1, 100.1),\n> +\t\t\t      static_cast<pointfOp>(&PointF::operator+), \"+\",\n> +\t\t\t      PointF(0, 200.2)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Dot product */\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(50.1, 100.1), PointF(50.1, 100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      12530.019999999999))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(50.1, 100.1), PointF(50.1, -100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      -7509.999999999998))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(50.1, 100.1), PointF(-50.1, 100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      7509.999999999998))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(50.1, 100.1), PointF(-50.1, -100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      -12530.019999999999))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(-50.1, 100.1), PointF(-50.1, 100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      12530.019999999999))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(50.1, -100.1), PointF(50.1, -100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      12530.019999999999))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(-50.1, -100.1), PointF(-50.1, -100.1),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      12530.019999999999))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareF<PointF, PointF, double>(PointF(0, 0), PointF(0, 0),\n> +\t\t\t      static_cast<pointfDotProd>(&PointF::operator%), \"%\",\n> +\t\t\t      0))\n> +\t\t\treturn TestFail;\n> +\n> +\n> +\t\t/* Scaling up */\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 0,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(0, 0)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 1,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(10.5, -100.1)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 1.0,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(10.5, -100.1)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), -4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(-44.1, 420.42)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(44.1, -420.42)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(0, -100.1), 4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(0, -420.42)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(-50.1, -100.1), 4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator*), \"*\",\n> +\t\t\t\t   PointF(-210.42000000000002, -420.42)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Scaling down */\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 1,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator/), \"/\",\n> +\t\t\t\t   PointF(10.5, -100.1)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 1.0,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator/), \"/\",\n> +\t\t\t\t   PointF(10.5, -100.1)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), -4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator/), \"/\",\n> +\t\t\t\t   PointF(-2.5, 23.833333333333332)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(10.5, -100.1), 4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator/), \"/\",\n> +\t\t\t\t   PointF(2.5, -23.833333333333332)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(0, -100.1), 4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator/), \"/\",\n> +\t\t\t\t   PointF(0, -23.833333333333332)))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFScale<PointF, double, PointF>(PointF(-50.1, -100.1), 4.2,\n> +\t\t\t\t   static_cast<pointfScale>(&PointF::operator/), \"/\",\n> +\t\t\t\t   PointF(-11.928571428571429, -23.833333333333332)))\n> +\t\t\treturn TestFail;\n> +\n> +\n> +\t\t/* Squared length */\n> +\t\tif (!compareFLen<PointF>(PointF(0, 0),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len2), \"len2\",\n> +\t\t\t\t\t 0))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(10.4, 0),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len2), \"len2\",\n> +\t\t\t\t\t 108.16000000000001))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(10.4, 50.1),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len2), \"len2\",\n> +\t\t\t\t\t 2618.17))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(-10.4, 50.1),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len2), \"len2\",\n> +\t\t\t\t\t 2618.17))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(-10.4, -50.1),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len2), \"len2\",\n> +\t\t\t\t\t 2618.17))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Length */\n> +\t\tif (!compareFLen<PointF>(PointF(0, 0),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len), \"len\",\n> +\t\t\t\t\t 0))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(10.4, 0),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len), \"len\",\n> +\t\t\t\t\t 10.4))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(10.4, 50.1),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len), \"len\",\n> +\t\t\t\t\t 51.16805644149483))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(-10.4, 50.1),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len), \"len\",\n> +\t\t\t\t\t 51.16805644149483))\n> +\t\t\treturn TestFail;\n> +\n> +\t\tif (!compareFLen<PointF>(PointF(-10.4, -50.1),\n> +\t\t\t\t\t static_cast<pointfLen>(&PointF::len), \"len\",\n> +\t\t\t\t\t 51.16805644149483))\n> +\t\t\treturn TestFail;\n> +\n> +\t\t/* Default constructor */\n> +\t\tif (PointF() != PointF(0, 0)) {\n> +\t\t\tcout << \"Default constructor test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n>  \t\t/*\n>  \t\t * Size tests\n>  \t\t */\n> -- \n> 2.39.2\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 3D584C3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  2 May 2024 19:19:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 22D6263418;\n\tThu,  2 May 2024 21:19:02 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B633633EB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  2 May 2024 21:19:00 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:1cc6:dc9:ae2:8e8a])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3297FC58;\n\tThu,  2 May 2024 21:18:02 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"D0h7uIIO\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1714677482;\n\tbh=FcuwSISVLRsSYtta2dgWu7lulVb22SEdlBBvVS4VISI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=D0h7uIIO1xpXvEcerhXWC6AD5cxXTpDSxdEFtMGKkXhLYNfeh1FcD3VtR4XU7iPJk\n\txrZzfQQenjwxmAKppD37UX2aogYnTxC/DyGhgGaaOLAkOWrHeBCAU6g0cMv9D96K/D\n\tFyttQCvHTYApwP8Uu29uHpIdOn416S+oqfc0Vb0Y=","Date":"Thu, 2 May 2024 21:18:56 +0200","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2 1/4] libcamera: geometry: Add floating-point version\n\tof Point class","Message-ID":"<20240502191856.eofrpevgkgx7j54c@jasper>","References":"<20240426073612.1230283-1-paul.elder@ideasonboard.com>\n\t<20240426073612.1230283-2-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20240426073612.1230283-2-paul.elder@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]