📄 drawarea2d.h
字号:
/* 2008 (c) Dorival M. Pedroso */#ifndef MPM_DRAWAREA2D_H#define MPM_DRAWAREA2D_H// STL#include <cmath> // for ceil and floor#include <cfloat> // for DBL_EPSILON// FLTK#include <FL/Fl.H>#include <FL/Fl_Input.H>#include <FL/Fl_Button.H>#include <FL/Fl_Group.H>#include <FL/fl_draw.H>#include <FL/Fl_Pixmap.H>#include <FL/Enumerations.H> // for Fl_Color// Local#include "defs.h"#include "fatal.h"#include "array.h"#include "grid2d.h"#include "tensors.h"#include "mpoints2d.h"#include "infobox.h"// Pixmaps#include "xpms/fixx.xpm"#include "xpms/fixy.xpm"#include "xpms/fixxy.xpm"/* Drawing area 2D. */class DrawArea2D : public Fl_Group{public: /* Constructor. */ DrawArea2D (int xmin, int ymin, int width, int height); // Screen coordinates /* Destructor. */ virtual ~DrawArea2D (); // Methods void SetGrid (Grid2D const * G) { _g = G; } ///< Set grid void SetPoints (MPoints2D const * P) { _p = P; } ///< Set material points void SetTime (double const * t) { _t = t; } ///< Set time void SetM (double const * M) { _M = M; } ///< Set multiplier for external forces void CalcSF (); ///< Calculate scale factors size_t SelP () const { return _selp; } ///< Return the selected mat point id size_t SelN () const { return _seln; } ///< Return the selected grid node id void ResetSelP (size_t i); ///< Set the selected mat point for output (reset previous to -1 => must call redraw()) // Set methods DrawArea2D & EqScales (bool EQScales=true) { _eqsf=EQScales; return (*this); } ///< Set equal scale factors DrawArea2D & RecalcSF (bool REcalcSF=true) { _recsf=REcalcSF; return (*this); } ///< Recalculate scale factors during draw ? DrawArea2D & WithFrame (bool WFrame =true) { _wframe=WFrame; return (*this); } ///< Draw an all-around frame ? /** Draw method (internal). */ void draw ();protected: /** Catch events. */ int handle (int E);private: // Widgets Fl_Input * _w_psz; ///< Point size Fl_Input * _w_gsz; ///< Grid size Fl_Button * _w_set; ///< Set all data // Data double _sfX; ///< Scale factor: x=xmin+(X-Xmin)*sf and y=ymin+ymax-(Y-Ymin)*sf, where x and y are screen coordinates double _sfY; ///< Scale factor: x=xmin+(X-Xmin)*sf and y=ymin+ymax-(Y-Ymin)*sf, where x and y are screen coordinates bool _eqsf; ///< Equal scale factors ? bool _recsf; ///< Recalculate scale factors during draw ? bool _sfok; ///< Is scale factor ok (set true after a first time calculation) ? bool _wframe; ///< With frame? draw an all-around frame ? double _Xmin; ///< Minimum x value (real coordinates) double _Ymin; ///< Minimum y value (real coordinates) double _Xmax; ///< Maximum x value (real coordinates) double _Ymax; ///< Maximum y value (real coordinates) int _hb; ///< Increment for horizontal borders (to the inside) (screen coordinates) int _vb; ///< Increment for vertical borders (to the inside) (screen coordinates) int _lfz; ///< Labels font size int _selp; ///< Selected material point int _seln; ///< Selected grid node int _pselp; ///< Previous selected material point int _pseln; ///< Previous selected grid node int _ctrh; ///< Control height // Elements Grid2D const * _g; ///< Grid MPoints2D const * _p; ///< Material points double const * _t; ///< Current time double const * _M; ///< Multiplier for external forces CurveProps _cg; ///< Curve properties for drawing nodes (the grid) CurveProps _cp; ///< Curve properties for drawing material points // XPMs Fl_Pixmap * _fixx; ///< Pixmap representing a X fixing icon Fl_Pixmap * _fixy; ///< Pixmap representing a Y fixing icon Fl_Pixmap * _fixxy; ///< Pixmap representing a XY fixing icon int _hf; ///< Fix pixmaps horizontal width int _vf; ///< Fix pixmaps vertical width // Private methods int _x (double X) const { return static_cast<int>((x()+1+_hb) +_sfX*(X-_Xmin)); } ///< X in screen coordinates int _y (double Y) const { return static_cast<int>((y()+1+_vb+_ctrh)+(h()-2-2*_vb-_ctrh)-_sfY*(Y-_Ymin)); } ///< Y in screen coordinates int _l (double L) const { return static_cast<int>((_sfX>_sfY?_sfY:_sfX)*L); } ///< Length in screen coordinates double _X (int xx) const { return _Xmin+(static_cast<double>(xx)-(x()+1+_hb))/_sfX; } ///< x in real coordinates double _Y (int yy) const { return _Ymin+((y()+1+_vb)+(h()-2-2*_vb)-static_cast<double>(yy))/_sfY; } ///< y in real coordinates // Private methods void _draw_vector_field (Array<Vector3D> const & P, Array<Vector3D> const & V, Fl_Color Clr); ///< Draw vector field void _draw_arrow (int xi, int yi, int xf, int yf, Fl_Color Clr=FL_BLUE); ///< Draw arrow void _draw_loaded_nodes (); ///< Draw loaded nodes void _draw_coords (); ///< Draw coordinates in a small rectangle, without redrawing entire screen void _draw_selected (); ///< Draw coordinates in a small rectangle, without redrawing entire screen void _draw_loaded_points(); // Callbacks (must be static) static void _set_cb (Fl_Widget * o, void * v) { ((DrawArea2D*)v)->_set(); } // Control methods void _set();}; // class DrawArea2D/////////////////////////////////////////////////////////////////////////////////////////// Implementation //////* public */inline DrawArea2D::DrawArea2D(int xmin, int ymin, int width, int height) : Fl_Group (xmin,ymin,width,height,0), _sfX (1.0), _sfY (1.0), _eqsf (true), _recsf (false), _sfok (false), _wframe (true), _Xmin (0.0), _Ymin (0.0), _Xmax (1.0), _Ymax (1.0), _lfz (8), _selp (-1), _seln (-1), _pselp (-1), _pseln (-1), _ctrh (25), _g (NULL), _p (NULL), _t (NULL), _M (NULL), _hf (15), _vf (15){ _w_psz = new Fl_Input (x(), y(), 0, 0, "pSz"); _w_gsz = new Fl_Input (x(), y(), 0, 0, "gSz"); _w_set = new Fl_Button (x(), y(), 0, 0, "Set"); end(); // Set curve properties for drawing nodes _cg.Typ = CT_BOTH; _cg.Clr = FL_GRAY; _cg.Lty = FL_SOLID; _cg.Lwd = 1; _cg.Pch = 1; _cg.Psz = 10; // Set curve properties for drawing material points _cp.Typ = CT_POINTS; _cp.Clr = FL_RED; _cp.Lty = FL_SOLID; _cp.Lwd = 1; _cp.Pch = 16; _cp.Psz = 15; // Borders _hb = 6+_hf+1; // 6 for border + hf for icons (xpms) _vb = 6+_vf+1; // 6 for border + vf for icons (xpms) // Set pixmaps _fixx = new Fl_Pixmap (fixx_xpm); _fixy = new Fl_Pixmap (fixy_xpm); _fixxy = new Fl_Pixmap (fixxy_xpm); // Initialize widgets char buf[256]; snprintf(buf, 256, "%d", _cp.Psz); _w_psz->value(buf); snprintf(buf, 256, "%d", _cg.Psz); _w_gsz->value(buf); // Callbacks _w_set->callback (_set_cb, this);}inline DrawArea2D::~DrawArea2D(){ delete _fixx; delete _fixy; delete _fixxy;}inline void DrawArea2D::CalcSF(){ // Check input if (_g==NULL) return; if (_g->nNodes()<2) return; // Bounding box _Xmin = _g->N(0)(0); _Ymin = _g->N(0)(1); _Xmax = _g->N(1)(0); _Ymax = _g->N(1)(1); for (size_t i=0; i<_g->nNodes(); ++i) { if (_g->N(i)(0)<_Xmin) _Xmin = _g->N(i)(0); if (_g->N(i)(0)>_Xmax) _Xmax = _g->N(i)(0); if (_g->N(i)(1)<_Ymin) _Ymin = _g->N(i)(1); if (_g->N(i)(1)>_Ymax) _Ymax = _g->N(i)(1); } // Scale factors _sfX = static_cast<double>((w()-2-2*_hb )/(_Xmax-_Xmin)); _sfY = static_cast<double>((h()-2-2*_vb-_ctrh)/(_Ymax-_Ymin)); if (_eqsf) { double sf = (_sfX>_sfY ? _sfY : _sfX); _sfX = sf; _sfY = sf; }}inline void DrawArea2D::ResetSelP(size_t i){ _pselp = -1; _selp = i;}inline void DrawArea2D::draw(){ // User damage ONLY ? if (damage()==FL_DAMAGE_USER1) { // Just draw coords and done _draw_coords(); return; } if (damage()==FL_DAMAGE_USER2) { // Just draw selected points or nodes and done _draw_selected(); return; } // Clear control background fl_color (FL_BACKGROUND_COLOR); fl_rectf (x(), y(), w(), _ctrh); // Let group draw itself _w_psz->resize(x()+200 , y(), 40, 25); _w_gsz->resize(x()+200+80 , y(), 40, 25); _w_set->resize(x()+200+120, y(), 60, _ctrh); Fl_Group::draw(); // Clear the background fl_color (FL_WHITE); fl_rectf (x(), y()+_ctrh, w(), h()-_ctrh); // Draw an all-around frame if (_wframe) { fl_color (FL_BLACK); fl_line_style (FL_SOLID, 1); fl_rect (x(), y()+_ctrh, w(), h()-_ctrh); } // Check input if (_g==NULL) return; if (_g->nNodes()<2) return; // Calculate scale factors and draw rulers if (_recsf || !_sfok) { CalcSF (); _sfok = true; } // Draw lines if (_cg.Typ==CT_LINES || _cg.Typ==CT_BOTH) { fl_color (_cg.Clr); fl_line_style (_cg.Lty, _cg.Lwd); for (int i=0; i<_g->nRow(); ++i) fl_line (_x(_g->xMin()), _y(_g->yMin()+i*_g->L(1)), _x(_g->xMax()), _y(_g->yMin()+i*_g->L(1))); for (int j=0; j<_g->nCol(); ++j) fl_line (_x(_g->xMin()+j*_g->L(0)), _y(_g->yMin()), _x(_g->xMin()+j*_g->L(0)), _y(_g->yMax())); } // Draw nodes if (_cg.Typ==CT_POINTS || _cg.Typ==CT_BOTH) { int r = _cg.Psz/2; if (_cg.Pch==1) // Open circle { fl_color (FL_BLACK); fl_line_style (FL_SOLID, 1); for (size_t i=0; i<_g->nNodes(); ++i) fl_circle (_x(_g->N(i)(0)), _y(_g->N(i)(1)), r); } else if (_cg.Pch==16) // Filled circle { fl_color (_cg.Clr); fl_line_style (FL_SOLID, 1); for (size_t i=0; i<_g->nNodes(); ++i) fl_pie (_x(_g->N(i)(0))-r, _y(_g->N(i)(1))-r, 2*r+1, 2*r+1, 0,360); } } // Draw fixed nodes for (size_t i=0; i<_g->nFix(); ++i) { int x = _x(_g->FixN(i)(0)); int y = _y(_g->FixN(i)(1)); switch (_g->FixT(i)) { case FIX_X : { _fixx->draw(x-_hf,y-_vf/2); break; } case FIX_Y : { _fixy->draw(x-_hf/2,y); break; } case FIX_Z : { break; } case FIX_XY : { _fixxy->draw(x-_hf/2,y); break; } case FIX_YZ : { break; } case FIX_ZX : { break; } case FIX_XYZ : { break; } } } // Draw cell ids char buf[256]; /* fl_font (0, 8); fl_color (FL_BLACK); for (size_t i=0; i<_g->nCells(); ++i) { int p0 = _g->C(i)(0); int p1 = _g->C(i)(1); int p2 = _g->C(i)(2); int p3 = _g->C(i)(3); int xc = _x(0.5*(_g->N(p0)(0)+_g->N(p2)(0))); int yc = _y(0.5*(_g->N(p0)(1)+_g->N(p2)(1))); snprintf (buf, 256, "%d\n(%d,%d,%d,%d)", i,p0,p1,p2,p3); // format text fl_draw (buf, xc, yc, 0, 0, FL_ALIGN_CENTER); // draw text } */ // Draw node ids /* for (size_t i=0; i<_g->nNodes(); ++i) { int xi = _x(_g->N(i)(0)); int yi = _y(_g->N(i)(1)); snprintf (buf, 256, "%d", i); fl_draw (buf, xi, yi, 0, 0, FL_ALIGN_CENTER); // draw text
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -