LinePointRep.cxx

Go to the documentation of this file.
00001 
00012 #ifdef _MSC_VER
00013 // include max() and min() missing from MicroSoft Visual C++
00014 #include "msdevstudio/MSconfig.h"
00015 #endif //_MSC_VER
00016 
00017 #include "LinePointRep.h"
00018 
00019 #include "axes/Range.h"
00020 #include "datasrcs/DataPointTuple.h"
00021 #include "datasrcs/DataSource.h"
00022 #include "graphics/ViewBase.h"
00023 #include "transforms/BinaryTransform.h"
00024 
00025 #include <limits>
00026 #include <cmath>
00027 #include <cassert>
00028 
00029 using namespace hippodraw;
00030 
00031 LinePointRep::LinePointRep ()
00032   : PointRepBase ( "Line", 1.0 ),
00033     m_line_style ( Line::Solid )
00034 {
00035 }
00036 
00037 LinePointRep::
00038 LinePointRep ( const char * name, float size )
00039   : PointRepBase ( name, size ),
00040     m_line_style ( Line::Solid )
00041 {
00042 }
00043 
00044 LinePointRep::LinePointRep ( float size )
00045   : PointRepBase ( "Line", size ),
00046     m_line_style ( Line::Solid )
00047 {
00048 }
00049 
00050 LinePointRep::LinePointRep ( const LinePointRep & point_rep )
00051   : PointRepBase ( point_rep ), 
00052     m_line_style ( point_rep.m_line_style )
00053 {
00054 }
00055 
00056 LinePointRep::~LinePointRep ()
00057 {
00058 }
00059 
00060 RepBase * LinePointRep::clone()
00061 {
00062   return new LinePointRep( *this );
00063 }
00064 
00065 void
00066 LinePointRep::
00067 setStyle ( unsigned int style )
00068 {
00069   m_line_style = Line::convert ( style );
00070 }
00071 
00072 unsigned int
00073 LinePointRep::
00074 getStyle ( ) const
00075 {
00076   return m_line_style;
00077 }
00078 
00079 namespace dp = hippodraw::DataPoint2DTuple;
00080 
00081 void
00082 LinePointRep::drawProjectedValues ( const DataSource * ntuple,
00083                                     TransformBase * transform,
00084                                     ViewBase * view )
00085 {
00086   transformValues ( ntuple, transform );
00087   drawValues ( view );
00088 }
00089 
00090 void
00091 LinePointRep::transformValues ( const DataSource * ntuple,
00092                                 TransformBase * transform )
00093 {
00094   unsigned int size = ntuple -> rows ();
00095   if ( size == 0 ) return;
00096 
00097   m_x.clear();
00098   m_y.clear();
00099 
00100   m_x.reserve ( size );
00101   m_y.reserve ( size );
00102 
00103   unsigned int i = 0; // for VC++ 7.1
00104   for ( ; i < size; i++ ) {
00105     const std::vector < double > & row = ntuple -> getRow ( i );
00106     double x = row [ dp::X ];    
00107     double y = row [ dp::Y ];
00108     m_x.push_back ( x );
00109     m_y.push_back ( y );
00110   }
00111   const BinaryTransform * t
00112     = dynamic_cast < const BinaryTransform * > ( transform );
00113 
00114   t -> transform ( m_x, m_y );
00115 }
00116 
00117 void LinePointRep::drawValues(ViewBase * view)
00118 {
00119   unsigned int size = m_x.size();
00120   if (size == 0)
00121     return;
00122 
00123   const Color & cur_color = color();
00124 
00125   m_user_rect = &(view -> getUserRect ());
00126   m_xmin = m_user_rect->getX ();
00127   m_xmax = m_xmin + m_user_rect->getWidth ();
00128   m_ymin = m_user_rect->getY ();
00129   m_ymax = m_ymin + m_user_rect->getHeight ();
00130 
00131   //special case: size is 1
00132   if (size == 1) {
00133     double const x0 = m_x[0];
00134     double const y0 = m_y[0];
00135 //     if (!((x0 < m_xmin) || (x0 > m_xmax)
00136 //        || (y0 > m_ymin) && (y0 < m_ymax))) {
00137 if ((x0 > m_xmin) && (x0 < m_xmax) && (y0 > m_ymin) && (y0 < m_ymax)) {
00138       std::vector<double> xdot, ydot;
00139       xdot.push_back(m_x[0]);
00140       ydot.push_back(m_y[0]);
00141       view->drawPoints(xdot, ydot, Symbol::SOLIDSQUARE, 2.0, cur_color);
00142     }
00143   }
00144 
00145   std::vector<double> xlines;
00146   std::vector<double> ylines;
00147   xlines.reserve ( size );
00148   ylines.reserve ( size );
00149 
00150   bool findBothCorners = true;
00151   bool secondCornerVisible;
00152   Point p0, p1, q0, q1;
00153 
00154   for (unsigned int i = 1; i < size; i++) {
00155     p0.setPoint(m_x[i - 1], m_y[i - 1]);
00156     p1.setPoint(m_x[i], m_y[i]);
00157     //needs to find also first point only if the previous point
00158     //was not in the view
00159     if (findIntersectingCorners(p0, p1, findBothCorners,
00160                                 q0, q1, secondCornerVisible) == true) {
00161       xlines.push_back(q0.getX());
00162       ylines.push_back(q0.getY());
00163       xlines.push_back(q1.getX());
00164       ylines.push_back(q1.getY());
00165       findBothCorners = !secondCornerVisible;
00166     }
00167   }
00168   if (xlines.empty() == false) {
00169     //tf -> transform(xlines, ylines);
00170     view->drawLines(xlines, ylines, m_line_style, cur_color, m_size); 
00171   }
00172 }
00173 
00174 
00175 bool LinePointRep::findIntersectingCorners(Point const &p0,
00176                                            Point const &p1,
00177                                            bool findBothCorners,
00178                                            Point &q0, Point &q1,
00179                                            bool &secondCornerVisible)
00180 {
00181   double tmin = -.5, tmax = .5;
00182   bool lineExists = false;
00183   secondCornerVisible = true;
00184 
00185   double const x0 = p0.getX();
00186   double const y0 = p0.getY();
00187   double const x1 = p1.getX();
00188   double const y1 = p1.getY();
00189 
00190   //calcolate the intersections with the vertical borders: N_e = (1, 0)
00191   double const dx = x1 - x0;
00192   double const xav = 0.5 * (x0 + x1);
00193   if (fabs(dx) > std::numeric_limits<double>::epsilon()) {
00194     //dx != 0 --> line is not vertical
00195     double const tl = (m_xmin - xav) / dx;
00196     double const tr = (m_xmax - xav) / dx;
00197     if (dx > 0) {
00198       if (findBothCorners) {
00199         if (tmin < tl) { tmin = tl; }
00200       }
00201       if (tmax > tr) { tmax = tr; secondCornerVisible = false; }
00202     } else {
00203       if (findBothCorners) {
00204         if (tmin < tr) { tmin = tr; }
00205       }
00206       if (tmax > tl) { tmax = tl; secondCornerVisible = false; }
00207     }
00208   } else {
00209     if ((x0 < m_xmin) || (x0 > m_xmax))
00210       return false;
00211   }
00212 
00213   //calcolate the intersections with the horizontal borders: N_e = (0, 1)
00214   double const dy = y1 - y0;
00215   double const yav = 0.5 * (y0 + y1);
00216   if (fabs(dy) > std::numeric_limits<double>::epsilon()) {
00217     //line is not horizontal
00218     double const tb = (m_ymin - yav) / dy;
00219     double const tt = (m_ymax - yav) / dy;
00220     if (dy > 0) {
00221       if (findBothCorners) {
00222         if (tmin < tb) { tmin = tb; }
00223       }
00224       if (tmax > tt) { tmax = tt; secondCornerVisible = false; }
00225     } else {
00226       if (findBothCorners) {
00227         if (tmin < tt) { tmin = tt; }
00228       }
00229       if (tmax > tb) { tmax = tb; secondCornerVisible = false; }
00230     }
00231   } else {
00232     if ((y0 < m_ymin) || (y0 > m_ymax))
00233       return false;
00234   }
00235 
00236   if (tmin <= tmax) {
00237     //line exists
00238     lineExists = true;
00239     q0.setPoint(xav + tmin * dx, yav + tmin * dy);
00240     q1.setPoint(xav + tmax * dx, yav + tmax * dy);
00241   }
00242   return lineExists;
00243 }
00244 
00245 bool
00246 LinePointRep::
00247 uses ( Line::Style ) const
00248 {
00249   return true;
00250 }

Generated for HippoDraw Class Library by doxygen