Skip to content

Commit

Permalink
Allow configuring the amount of digits displayed after decimal point.
Browse files Browse the repository at this point in the history
This is useful in niche cases, like making angular measurement tools.

Also, use simpler and more principled code for numeric precision
while editing constraints: don't special-case angles, but use up to
10 digits after the decimal point for everything.
  • Loading branch information
whitequark committed May 23, 2019
1 parent d01f715 commit ac7b82d
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 40 deletions.
25 changes: 22 additions & 3 deletions src/confscreen.cpp
Expand Up @@ -60,10 +60,15 @@ void TextWindow::ScreenChangeGridSpacing(int link, uint32_t v) {
}

void TextWindow::ScreenChangeDigitsAfterDecimal(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%d", SS.UnitDigitsAfterDecimal()));
SS.TW.ShowEditControl(14, ssprintf("%d", SS.UnitDigitsAfterDecimal()));
SS.TW.edit.meaning = Edit::DIGITS_AFTER_DECIMAL;
}

void TextWindow::ScreenChangeDigitsAfterDecimalDegree(int link, uint32_t v) {
SS.TW.ShowEditControl(14, ssprintf("%d", SS.afterDecimalDegree));
SS.TW.edit.meaning = Edit::DIGITS_AFTER_DECIMAL_DEGREE;
}

void TextWindow::ScreenChangeExportScale(int link, uint32_t v) {
SS.TW.ShowEditControl(5, ssprintf("%.3f", (double)SS.exportScale));
SS.TW.edit.meaning = Edit::EXPORT_SCALE;
Expand Down Expand Up @@ -235,10 +240,14 @@ void TextWindow::ShowConfiguration() {
SS.MmToString(SS.gridSpacing).c_str(),
&ScreenChangeGridSpacing, 0);
Printf(false, "%Ft digits after decimal point to show%E");
Printf(false, "%Ba %d %Fl%Ll%f%D[change]%E (e.g. '%s')",
Printf(false, "%Ba%Ft distances: %Fd%d %Fl%Ll%f%D[change]%E (e.g. '%s')",
SS.UnitDigitsAfterDecimal(),
&ScreenChangeDigitsAfterDecimal, 0,
SS.MmToString(SS.StringToMm("1.23456789")).c_str());
Printf(false, "%Ba%Ft angles: %Fd%d %Fl%Ll%f%D[change]%E (e.g. '%s')",
SS.afterDecimalDegree,
&ScreenChangeDigitsAfterDecimalDegree, 0,
SS.DegreeToString(1.23456789).c_str());

Printf(false, "");
Printf(false, "%Ft export scale factor (1:1=mm, 1:25.4=inch)");
Expand Down Expand Up @@ -400,13 +409,23 @@ bool TextWindow::EditControlDoneForConfiguration(const std::string &s) {
case Edit::DIGITS_AFTER_DECIMAL: {
int v = atoi(s.c_str());
if(v < 0 || v > 8) {
Error(_("Specify between 0 and 8 digits after the decimal."));
Error(_("Specify between 0 and %d digits after the decimal."), 8);
} else {
SS.SetUnitDigitsAfterDecimal(v);
SS.GW.Invalidate();
}
break;
}
case Edit::DIGITS_AFTER_DECIMAL_DEGREE: {
int v = atoi(s.c_str());
if(v < 0 || v > 4) {
Error(_("Specify between 0 and %d digits after the decimal."), 4);
} else {
SS.afterDecimalDegree = v;
SS.GW.Invalidate();
}
break;
}
case Edit::EXPORT_SCALE: {
Expr *e = Expr::From(s, /*popUpError=*/true);
if(e) {
Expand Down
6 changes: 1 addition & 5 deletions src/drawconstraint.cpp
Expand Up @@ -11,11 +11,7 @@
std::string Constraint::Label() const {
std::string result;
if(type == Type::ANGLE) {
if(valA == floor(valA)) {
result = ssprintf("%.0f°", valA);
} else {
result = ssprintf("%.2f°", valA);
}
result = SS.DegreeToString(valA) + "°";
} else if(type == Type::LENGTH_RATIO) {
result = ssprintf("%.3f:1", valA);
} else if(type == Type::COMMENT) {
Expand Down
42 changes: 18 additions & 24 deletions src/mouse.cpp
Expand Up @@ -1361,36 +1361,30 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
editPlaceholder = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
break;

case Constraint::Type::ANGLE:
case Constraint::Type::LENGTH_RATIO:
editValue = ssprintf("%.3f", c->valA);
editPlaceholder = "0.000";
break;

default: {
double v = fabs(c->valA);
double value = fabs(c->valA);

// If displayed as radius, also edit as radius.
if(c->type == Constraint::Type::DIAMETER && c->other)
v /= 2;

std::string def = SS.MmToString(v);
double eps = 1e-12;
if(fabs(SS.StringToMm(def) - v) < eps) {
// Show value with default number of digits after decimal,
// which is at least enough to represent it exactly.
editValue = def;
value /= 2;

// Try showing value with default number of digits after decimal first.
if(c->type == Constraint::Type::LENGTH_RATIO) {
editValue = ssprintf("%.3f", value);
} else if(c->type == Constraint::Type::ANGLE) {
editValue = SS.DegreeToString(value);
} else {
// Show value with as many digits after decimal as
// required to represent it exactly, up to 10.
v /= SS.MmPerUnit();
int i;
for(i = 0; i <= 10; i++) {
editValue = ssprintf("%.*f", i, v);
if(fabs(std::stod(editValue) - v) < eps) break;
}
editValue = SS.MmToString(value);
value /= SS.MmPerUnit();
}
// If that's not enough to represent it exactly, show the value with as many
// digits after decimal as required, up to 10.
int digits = 0;
while(fabs(std::stod(editValue) - value) > 1e-10) {
editValue = ssprintf("%.*f", digits, value);
digits++;
}
editPlaceholder = "0.00000";
editPlaceholder = "10.000000";
break;
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/solvespace.cpp
Expand Up @@ -56,6 +56,7 @@ void SolveSpaceUI::Init() {
// Number of digits after the decimal point
afterDecimalMm = settings->ThawInt("AfterDecimalMm", 2);
afterDecimalInch = settings->ThawInt("AfterDecimalInch", 3);
afterDecimalDegree = settings->ThawInt("AfterDecimalDegree", 2);
// Camera tangent (determines perspective)
cameraTangent = settings->ThawFloat("CameraTangent", 0.3f/1e3);
// Grid spacing
Expand Down Expand Up @@ -229,6 +230,7 @@ void SolveSpaceUI::Exit() {
// Number of digits after the decimal point
settings->FreezeInt("AfterDecimalMm", (uint32_t)afterDecimalMm);
settings->FreezeInt("AfterDecimalInch", (uint32_t)afterDecimalInch);
settings->FreezeInt("AfterDecimalDegree", (uint32_t)afterDecimalDegree);
// Camera tangent (determines perspective)
settings->FreezeFloat("CameraTangent", (float)cameraTangent);
// Grid spacing
Expand Down Expand Up @@ -320,6 +322,13 @@ std::string SolveSpaceUI::MmToString(double v) {
}
return "";
}
std::string SolveSpaceUI::DegreeToString(double v) {
if(fabs(v - floor(v)) > 1e-10) {
return ssprintf("%.*f", afterDecimalDegree, v);
} else {
return ssprintf("%.0f", v);
}
}
double SolveSpaceUI::ExprToMm(Expr *e) {
return (e->Eval()) * MmPerUnit();
}
Expand Down
2 changes: 2 additions & 0 deletions src/solvespace.h
Expand Up @@ -621,9 +621,11 @@ class SolveSpaceUI {
Unit viewUnits;
int afterDecimalMm;
int afterDecimalInch;
int afterDecimalDegree;
int autosaveInterval; // in minutes

std::string MmToString(double v);
std::string DegreeToString(double v);
double ExprToMm(Expr *e);
double StringToMm(const std::string &s);
const char *UnitName();
Expand Down
18 changes: 10 additions & 8 deletions src/ui.h
Expand Up @@ -300,14 +300,15 @@ class TextWindow {
CAMERA_TANGENT = 105,
GRID_SPACING = 106,
DIGITS_AFTER_DECIMAL = 107,
EXPORT_SCALE = 108,
EXPORT_OFFSET = 109,
CANVAS_SIZE = 110,
G_CODE_DEPTH = 120,
G_CODE_PASSES = 121,
G_CODE_FEED = 122,
G_CODE_PLUNGE_FEED = 123,
AUTOSAVE_INTERVAL = 124,
DIGITS_AFTER_DECIMAL_DEGREE = 108,
EXPORT_SCALE = 109,
EXPORT_OFFSET = 110,
CANVAS_SIZE = 111,
G_CODE_DEPTH = 112,
G_CODE_PASSES = 113,
G_CODE_FEED = 114,
G_CODE_PLUNGE_FEED = 115,
AUTOSAVE_INTERVAL = 116,
// For TTF text
TTF_TEXT = 300,
// For the step dimension screen
Expand Down Expand Up @@ -467,6 +468,7 @@ class TextWindow {
static void ScreenChangeCameraTangent(int link, uint32_t v);
static void ScreenChangeGridSpacing(int link, uint32_t v);
static void ScreenChangeDigitsAfterDecimal(int link, uint32_t v);
static void ScreenChangeDigitsAfterDecimalDegree(int link, uint32_t v);
static void ScreenChangeExportScale(int link, uint32_t v);
static void ScreenChangeExportOffset(int link, uint32_t v);
static void ScreenChangeGCodeParameter(int link, uint32_t v);
Expand Down

0 comments on commit ac7b82d

Please sign in to comment.