From 08f37deaddff86ccb628b3b61b86a51b2d34b9ed Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sat, 21 Nov 2020 19:16:45 -0500 Subject: [PATCH] Make better choices of SI units by considering order. --- src/solvespace.cpp | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 7c30a8f5..9b3ef9b3 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -341,13 +341,39 @@ static const char *DimToString(int dim) { default: ssassert(false, "Unexpected dimension"); } } -static std::pair SelectSIPrefixMm(int deg) { - if(deg >= 3) return { 3, "km" }; - else if(deg >= 0) return { 0, "m" }; - else if(deg >= -2) return { -2, "cm" }; - else if(deg >= -3) return { -3, "mm" }; - else if(deg >= -6) return { -6, "µm" }; - else return { -9, "nm" }; +static std::pair SelectSIPrefixMm(int ord, int dim) { +// decide what units to use depending on the order of magnitude of the +// measure in meters and the dimmension (1,2,3 lenear, area, volume) + switch(dim) { + case 0: + case 1: + if(ord >= 3) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -2) return { -2, "cm" }; + else if(ord >= -3) return { -3, "mm" }; + else if(ord >= -6) return { -6, "µm" }; + else return { -9, "nm" }; + break; + case 2: + if(ord >= 5) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -2) return { -2, "cm" }; + else if(ord >= -6) return { -3, "mm" }; + else if(ord >= -13) return { -6, "µm" }; + else return { -9, "nm" }; + break; + case 3: + if(ord >= 7) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -5) return { -2, "cm" }; + else if(ord >= -11) return { -3, "mm" }; + else return { -6, "µm" }; + break; + default: + dbp ("dimensions over 3 not supported"); + break; + } + return {0, "m"}; } static std::pair SelectSIPrefixInch(int deg) { if(deg >= 0) return { 0, "in" }; @@ -363,14 +389,14 @@ std::string SolveSpaceUI::MmToStringSI(double v, int dim) { } v /= pow((viewUnits == Unit::INCHES) ? 25.4 : 1000, dim); - int vdeg = (int)((log10(fabs(v))) / dim); + int vdeg = (int)(log10(fabs(v))); std::string unit; if(fabs(v) > 0.0) { int sdeg = 0; std::tie(sdeg, unit) = (viewUnits == Unit::INCHES) - ? SelectSIPrefixInch(vdeg) - : SelectSIPrefixMm(vdeg); + ? SelectSIPrefixInch(vdeg/dim) + : SelectSIPrefixMm(vdeg, dim); v /= pow(10.0, sdeg * dim); } int pdeg = (int)ceil(log10(fabs(v) + 1e-10));