00001
00012 #ifdef _MSC_VER
00013
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;
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
00132 if (size == 1) {
00133 double const x0 = m_x[0];
00134 double const y0 = m_y[0];
00135
00136
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
00158
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
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
00191 double const dx = x1 - x0;
00192 double const xav = 0.5 * (x0 + x1);
00193 if (fabs(dx) > std::numeric_limits<double>::epsilon()) {
00194
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
00214 double const dy = y1 - y0;
00215 double const yav = 0.5 * (y0 + y1);
00216 if (fabs(dy) > std::numeric_limits<double>::epsilon()) {
00217
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
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 }