1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
From 57de65483771adc2da738afbe94f7a83a1bcc496 Mon Sep 17 00:00:00 2001
From: Gregor Riepl <onitake@gmail.com>
Date: Tue, 18 Jul 2023 23:12:33 +0000
Subject: [PATCH] Round from double to cInt explicitly when applying matrices.
This avoids subtle errors when the default rounding more is truncate.
---
src/utils/IntPoint.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/src/utils/IntPoint.h
+++ b/src/utils/IntPoint.h
@@ -50,7 +50,7 @@
INLINE Point operator-(const Point& p0, const Point& p1) { return Point(p0.X-p1.X, p0.Y-p1.Y); }
INLINE Point operator*(const Point& p0, const coord_t i) { return Point(p0.X * i, p0.Y * i); }
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type> //Use only for numeric types.
-INLINE Point operator*(const Point& p0, const T i) { return Point(p0.X * i, p0.Y * i); }
+INLINE Point operator*(const Point& p0, const T i) { return Point(std::llrint(p0.X * i), std::llrint(p0.Y * i)); }
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type> //Use only for numeric types.
INLINE Point operator*(const T i, const Point& p0) { return p0 * i; }
INLINE Point operator/(const Point& p0, const coord_t i) { return Point(p0.X/i, p0.Y/i); }
@@ -263,9 +263,9 @@
Point3 apply(const Point3 p) const
{
- return Point3(p.x * matrix[0] + p.y * matrix[1] + p.z * matrix[2]
- , p.x * matrix[3] + p.y * matrix[4] + p.z * matrix[5]
- , p.x * matrix[6] + p.y * matrix[7] + p.z * matrix[8]);
+ return Point3(std::llrint(p.x * matrix[0] + p.y * matrix[1] + p.z * matrix[2])
+ , std::llrint(p.x * matrix[3] + p.y * matrix[4] + p.z * matrix[5])
+ , std::llrint(p.x * matrix[6] + p.y * matrix[7] + p.z * matrix[8]));
}
/*!
--- a/tests/arcus/ArcusCommunicationPrivateTest.cpp
+++ b/tests/arcus/ArcusCommunicationPrivateTest.cpp
@@ -4,6 +4,7 @@
#include <array>
#include <gtest/gtest.h>
#include <fstream>
+#include <cmath>
#include "MockSocket.h"
#include "../../src/Application.h"
@@ -227,7 +228,7 @@
const size_t num_vertex = raw_vertices.size();
for (size_t i_coord = 0; i_coord < num_vertex; ++i_coord)
{
- coord_t micrometers = static_cast<coord_t>(raw_vertices[i_coord] * 1000.f);
+ coord_t micrometers = static_cast<coord_t>(std::llrintf(raw_vertices[i_coord] * 1000.f));
raw_min_coords[i_coord % 3] = std::min(micrometers, raw_min_coords[i_coord % 3]);
raw_max_coords[i_coord % 3] = std::max(micrometers, raw_max_coords[i_coord % 3]);
}
|