mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-20 15:24:14 +02:00
Fix: positionKey() didn't sort coordinates numerically
Plain fixed-precision formatting ("%.4f") produces strings that don't
compare in numeric order once the integer part has a different digit
count -- e.g. "15.0000" sorts before "5.0000" as text, even though
15 > 5. That silently broke the determinism goal of this branch for
any diagram with coordinates spanning more than one digit width.
Shift into a non-negative range and zero-pad to a fixed width instead,
so the formatted string sorts the same way the number does, including
negative values.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+16
-5
@@ -45,13 +45,24 @@
|
||||
#include <math.h>
|
||||
|
||||
namespace {
|
||||
/// Format a position as a string that sorts the same way the numbers do
|
||||
/// (fixed precision, so "-" and decimals compare correctly as text).
|
||||
/// Format a coordinate as a string that sorts the same way the number
|
||||
/// does. Plain fixed-precision formatting ("%.4f") does NOT do this --
|
||||
/// e.g. "15.0000" sorts before "5.0000" as text even though 15 > 5 --
|
||||
/// so shift into a non-negative range and zero-pad to a fixed width
|
||||
/// before comparing.
|
||||
QString coordinateKey(double v)
|
||||
{
|
||||
//Diagram coordinates are nowhere near this range; the offset and
|
||||
//width just need to be big enough that shifted values are always
|
||||
//non-negative and always the same digit count.
|
||||
constexpr double offset = 1e9;
|
||||
qint64 scaled = qint64(qRound64((v + offset) * 10000.0));
|
||||
return QStringLiteral("%1").arg(scaled, 20, 10, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
QString positionKey(const QPointF &pos)
|
||||
{
|
||||
return QStringLiteral("%1|%2")
|
||||
.arg(pos.x(), 0, 'f', 4)
|
||||
.arg(pos.y(), 0, 'f', 4);
|
||||
return coordinateKey(pos.x()) + QLatin1Char('|') + coordinateKey(pos.y());
|
||||
}
|
||||
|
||||
/// Sort key for Diagram::toXml()'s <elements> block: the element's own
|
||||
|
||||
Reference in New Issue
Block a user