Make better choices of SI units by considering order.

pull/818/head
phkahler 2020-11-21 19:16:45 -05:00
parent 5137da295a
commit 08f37deadd
1 changed files with 36 additions and 10 deletions

View File

@ -341,13 +341,39 @@ static const char *DimToString(int dim) {
default: ssassert(false, "Unexpected dimension"); default: ssassert(false, "Unexpected dimension");
} }
} }
static std::pair<int, std::string> SelectSIPrefixMm(int deg) { static std::pair<int, std::string> SelectSIPrefixMm(int ord, int dim) {
if(deg >= 3) return { 3, "km" }; // decide what units to use depending on the order of magnitude of the
else if(deg >= 0) return { 0, "m" }; // measure in meters and the dimmension (1,2,3 lenear, area, volume)
else if(deg >= -2) return { -2, "cm" }; switch(dim) {
else if(deg >= -3) return { -3, "mm" }; case 0:
else if(deg >= -6) return { -6, "µm" }; case 1:
else return { -9, "nm" }; 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<int, std::string> SelectSIPrefixInch(int deg) { static std::pair<int, std::string> SelectSIPrefixInch(int deg) {
if(deg >= 0) return { 0, "in" }; 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); 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; std::string unit;
if(fabs(v) > 0.0) { if(fabs(v) > 0.0) {
int sdeg = 0; int sdeg = 0;
std::tie(sdeg, unit) = std::tie(sdeg, unit) =
(viewUnits == Unit::INCHES) (viewUnits == Unit::INCHES)
? SelectSIPrefixInch(vdeg) ? SelectSIPrefixInch(vdeg/dim)
: SelectSIPrefixMm(vdeg); : SelectSIPrefixMm(vdeg, dim);
v /= pow(10.0, sdeg * dim); v /= pow(10.0, sdeg * dim);
} }
int pdeg = (int)ceil(log10(fabs(v) + 1e-10)); int pdeg = (int)ceil(log10(fabs(v) + 1e-10));