From 5f88a6c5f8cbabd9b89dd1b59c17c719300e5a89 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Fri, 3 Aug 2012 08:29:16 +0000 Subject: [PATCH] automatically adjust number of axis tics --- Common/Context.h | 4 +- Common/Options.cpp | 12 ++--- Graphics/drawAxes.cpp | 94 ++++++++++++++++++---------------------- Graphics/drawContext.h | 4 +- Graphics/drawGraph2d.cpp | 4 +- Post/PViewOptions.h | 3 +- 6 files changed, 56 insertions(+), 65 deletions(-) diff --git a/Common/Context.h b/Common/Context.h index b7b176c0cf..a27373bf6a 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -149,8 +149,8 @@ class CTX { // small axes options int smallAxes, smallAxesSize, smallAxesPos[2]; // large axes options - int axes, axesAutoPosition, axesTics[3], axesMikado, axesForceValue; - double axesPosition[6], axesValue[6]; + int axes, axesAutoPosition, axesMikado, axesForceValue; + double axesPosition[6], axesValue[6], axesTics[3]; std::string axesLabel[3], axesFormat[3]; // simple dynamic lock (should be a mutex) int lock; diff --git a/Common/Options.cpp b/Common/Options.cpp index 48f617ed24..09991224f1 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -2575,7 +2575,7 @@ double opt_general_axes_auto_position(OPT_ARGS_NUM) double opt_general_axes_tics0(OPT_ARGS_NUM) { if(action & GMSH_SET) - CTX::instance()->axesTics[0] = (int)val; + CTX::instance()->axesTics[0] = val; #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI)) FlGui::instance()->options->general.value[17]->value @@ -2587,7 +2587,7 @@ double opt_general_axes_tics0(OPT_ARGS_NUM) double opt_general_axes_tics1(OPT_ARGS_NUM) { if(action & GMSH_SET) - CTX::instance()->axesTics[1] = (int)val; + CTX::instance()->axesTics[1] = val; #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI)) FlGui::instance()->options->general.value[18]->value @@ -2599,7 +2599,7 @@ double opt_general_axes_tics1(OPT_ARGS_NUM) double opt_general_axes_tics2(OPT_ARGS_NUM) { if(action & GMSH_SET) - CTX::instance()->axesTics[2] = (int)val; + CTX::instance()->axesTics[2] = val; #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI)) FlGui::instance()->options->general.value[19]->value @@ -6853,7 +6853,7 @@ double opt_view_axes_tics0(OPT_ARGS_NUM) #if defined(HAVE_POST) GET_VIEW(0.); if(action & GMSH_SET) { - opt->axesTics[0] = (int)val; + opt->axesTics[0] = val; } #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)) { @@ -6871,7 +6871,7 @@ double opt_view_axes_tics1(OPT_ARGS_NUM) #if defined(HAVE_POST) GET_VIEW(0.); if(action & GMSH_SET) { - opt->axesTics[1] = (int)val; + opt->axesTics[1] = val; } #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)) { @@ -6889,7 +6889,7 @@ double opt_view_axes_tics2(OPT_ARGS_NUM) #if defined(HAVE_POST) GET_VIEW(0.); if(action & GMSH_SET) { - opt->axesTics[2] = (int)val; + opt->axesTics[2] = val; } #if defined(HAVE_FLTK) if(_gui_action_valid(action, num)) { diff --git a/Graphics/drawAxes.cpp b/Graphics/drawAxes.cpp index 59a7b63ea6..897b8d2b82 100644 --- a/Graphics/drawAxes.cpp +++ b/Graphics/drawAxes.cpp @@ -14,7 +14,9 @@ #include "Numeric.h" #include "gl2ps.h" -static int drawTics(drawContext *ctx, int comp, int n, std::string &format, +#define SQU(a) ((a)*(a)) + +static int drawTics(drawContext *ctx, int comp, double n, std::string &format, std::string &label, double p1[3], double p2[3], double perp[3], int mikado, double pixelfact, double value_p1[3], double value_p2[3]) @@ -26,18 +28,18 @@ static int drawTics(drawContext *ctx, int comp, int n, std::string &format, double value_t[3] = {value_p2[0] - value_p1[0], value_p2[1] - value_p1[1], value_p2[2] - value_p1[2]}; double value_l = norme(value_t); - double w = 10 * pixelfact; // big tics 10 pixels - double w2 = 5 * pixelfact; // small tics 5 pixels + double w = 10 * pixelfact; // tic marks are 10 pixels long + double w2 = w * 1.3; // distance to labels - glRasterPos3d(p2[0] + t[0] * w * 1.4, - p2[1] + t[1] * w * 1.4, - p2[2] + t[2] * w * 1.4); + // draw label at the end of the axis + glRasterPos3d(p2[0] + t[0] * w2, p2[1] + t[1] * w2, p2[2] + t[2] * w2); ctx->drawString(label); + // return number of tics in special cases if(n < 2) return 0; - if(format.empty()) return n; + // select perp direction automatically if it is not provided double lp = norme(perp); if(!lp){ switch(comp){ @@ -48,22 +50,28 @@ static int drawTics(drawContext *ctx, int comp, int n, std::string &format, } } - double tmp = 2. * CTX::instance()->glFontSize * pixelfact; - if(n * tmp > l) n = 3; - if(n * tmp > l) n = 2; - + // reduce number of tics depending on font size and length of axis on screen + drawContext::global()->setFont(CTX::instance()->glFontEnum, + CTX::instance()->glFontSize); + char tmp[256]; + sprintf(tmp, format.c_str(), -M_PI * 1.e4); + double win1[3], win2[3]; + ctx->world2Viewport(p1, win1); + ctx->world2Viewport(p2, win2); + double winl = sqrt(SQU(win2[0] - win1[0]) + SQU(win2[1] - win1[1])); + double strl = drawContext::global()->getStringWidth(tmp); + if((n - 1) * strl > winl) n = (int)(winl / strl) + 1; + if(n <= 1) n = 2; + + // draw n tics double step = l / (double)(n - 1); double value_step = value_l / (double)(n - 1); for(int i = 0; i < n; i++){ double d = i * step; double p[3] = {p1[0] + t[0] * d, p1[1] + t[1] * d, p1[2] + t[2] * d}; - double q[3] = {p[0] + perp[0] * w, - p[1] + perp[1] * w, - p[2] + perp[2] * w}; - double r[3] = {p[0] + perp[0] * w * 1.4, - p[1] + perp[1] * w * 1.4, - p[2] + perp[2] * w * 1.4 }; + double q[3] = {p[0] + perp[0] * w, p[1] + perp[1] * w, p[2] + perp[2] * w}; + double r[3] = {p[0] + perp[0] * w2, p[1] + perp[1] * w2, p[2] + perp[2] * w2}; double value_d = i * value_step; double value_p[3] = {value_p1[0] + value_t[0] * value_d, @@ -75,43 +83,25 @@ static int drawTics(drawContext *ctx, int comp, int n, std::string &format, glVertex3d(q[0], q[1], q[2]); glEnd(); - if(i < n-1 && !mikado){ - for(int j = 1; j < 10; j++){ - double dd = d + j * step/10.; - double pp[3] = {p1[0] + t[0] * dd, - p1[1] + t[1] * dd, - p1[2] + t[2] * dd}; - double qq[3] = {pp[0] + perp[0] * w2, - pp[1] + perp[1] * w2, - pp[2] + perp[2] * w2}; - glBegin(GL_LINES); - glVertex3d(pp[0], pp[1], pp[2]); - glVertex3d(qq[0], qq[1], qq[2]); - glEnd(); - } - } - - char str[256]; - if(comp < 0) // display the length (ruler) - sprintf(str, format.c_str(), value_d); - else // display the coordinate - sprintf(str, format.c_str(), value_p[comp]); + // draw tic labels + if(comp < 0) // display the length value (ruler-mode, starting at 0) + sprintf(tmp, format.c_str(), value_d); + else // display the coordinate value + sprintf(tmp, format.c_str(), value_p[comp]); double winp[3], winr[3]; ctx->world2Viewport(p, winp); ctx->world2Viewport(r, winr); - drawContext::global()->setFont(CTX::instance()->glFontEnum, - CTX::instance()->glFontSize); if(fabs(winr[0] - winp[0]) < 2.) // center align - winr[0] -= drawContext::global()->getStringWidth(str) / 2.; + winr[0] -= drawContext::global()->getStringWidth(tmp) / 2.; else if(winr[0] < winp[0]) // right align - winr[0] -= drawContext::global()->getStringWidth(str); + winr[0] -= drawContext::global()->getStringWidth(tmp); if(fabs(winr[1] - winp[1]) < 2.) // center align winr[1] -= drawContext::global()->getStringHeight() / 3.; else if(winr[1] < winp[1]) // top align winr[1] -= drawContext::global()->getStringHeight(); ctx->viewport2World(winr, r); glRasterPos3d(r[0], r[1], r[2]); - ctx->drawString(str); + ctx->drawString(tmp); } return n; @@ -155,17 +145,17 @@ static void drawGridStipple(int n1, int n2, double p1[3], double p2[3], double p void drawContext::drawAxis(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, - int nticks, int mikado) + int ntics, int mikado) { if(mikado){ - nticks = (nticks - 1) * mikado; - if(nticks < 1) nticks = 1; - double dd[3] = {(xmax - xmin) / nticks, - (ymax - ymin) / nticks, - (zmax - zmin) / nticks}; + ntics = (ntics - 1) * mikado; + if(ntics < 1) ntics = 1; + double dd[3] = {(xmax - xmin) / ntics, + (ymax - ymin) / ntics, + (zmax - zmin) / ntics}; double axe_color[4]; glGetDoublev(GL_CURRENT_COLOR, axe_color); - for(int i = 1; i <= nticks; i++){ + for(int i = 1; i <= ntics; i++){ if(i % 2) glColor4dv(axe_color); else glColor3f(1, 1, 1); double cx[2] = {xmin + (i - 1) * dd[0], xmin + i * dd[0]}; @@ -183,7 +173,7 @@ void drawContext::drawAxis(double xmin, double ymin, double zmin, } } -void drawContext::drawAxes(int mode, int tics[3], std::string format[3], +void drawContext::drawAxes(int mode, double tics[3], std::string format[3], std::string label[3], double bb[6], int mikado, double value_bb[6]) { @@ -281,7 +271,7 @@ void drawContext::drawAxes(int mode, int tics[3], std::string format[3], } } -void drawContext::drawAxes(int mode, int tics[3], std::string format[3], +void drawContext::drawAxes(int mode, double tics[3], std::string format[3], std::string label[3], SBoundingBox3d &bb, int mikado, SBoundingBox3d &value_bb) { diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h index 0c2c03b717..42ff998e1f 100644 --- a/Graphics/drawContext.h +++ b/Graphics/drawContext.h @@ -189,9 +189,9 @@ class drawContext { void drawAxis(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, int nticks, int mikado); - void drawAxes(int mode, int tics[3], std::string format[3], + void drawAxes(int mode, double tics[3], std::string format[3], std::string label[3], double bb[6], int mikado, double value_bb[6]); - void drawAxes(int mode, int tics[3], std::string format[3], + void drawAxes(int mode, double tics[3], std::string format[3], std::string label[3], SBoundingBox3d &bb, int mikado, SBoundingBox3d &value_bb); void drawAxes(); void drawSmallAxes(); diff --git a/Graphics/drawGraph2d.cpp b/Graphics/drawGraph2d.cpp index dcfd0f0e4f..a146aa3098 100644 --- a/Graphics/drawGraph2d.cpp +++ b/Graphics/drawGraph2d.cpp @@ -299,7 +299,7 @@ static void drawGraphAxes(drawContext *ctx, PView *p, double xleft, double ytop, int nb = opt->axesTics[0]; if(opt->axes){ char tmp[256]; - sprintf(tmp, opt->axesFormat[0].c_str(), - M_PI * 1.e-4); + sprintf(tmp, opt->axesFormat[0].c_str(), -M_PI * 1.e4); if((nb - 1) * drawContext::global()->getStringWidth(tmp) > width) nb = (int)(width / drawContext::global()->getStringWidth(tmp)) + 1; } @@ -487,7 +487,7 @@ void drawContext::drawGraph2d() char label[1024]; for(unsigned int i = 0; i < graphs.size(); i++){ PViewOptions *opt = graphs[i]->getOptions(); - sprintf(label, opt->format.c_str(), -M_PI * 1.e-4); + sprintf(label, opt->format.c_str(), -M_PI * 1.e4); xsep = std::max(xsep, drawContext::global()->getStringWidth(label)); } diff --git a/Post/PViewOptions.h b/Post/PViewOptions.h index 24f09a4cfe..56bfbc5dcd 100644 --- a/Post/PViewOptions.h +++ b/Post/PViewOptions.h @@ -60,7 +60,8 @@ class PViewOptions { int type; int position[2], size[2], autoPosition; std::string format; - int axes, axesAutoPosition, axesMikado, axesTics[3]; + int axes, axesAutoPosition, axesMikado; + double axesTics[3]; std::string axesFormat[3], axesLabel[3]; double axesPosition[6]; double customMin, customMax, tmpMin, tmpMax, externalMin, externalMax; -- GitLab