00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00025
00026
00027
00029
00030
00031 #include <qpainter.h>
00032 #include <qpixmap.h>
00033
00034
00035 #include "plotmaplabel.h"
00036
00040
00042 PlotMapLabel::PlotMapLabel(QWidget* parent, const char* name, WFlags fl) : QLabel(parent, name, fl),
00043 densityPixmap(NULL),
00044 drawDrag(false)
00046 {
00047 }
00048
00050 PlotMapLabel::~PlotMapLabel()
00052 {
00053 if(densityPixmap)
00054 delete densityPixmap;
00055 }
00056
00058 void PlotMapLabel::setDrawStyle(const unsigned int style, const bool cubic)
00064 {
00065 if(style > 3)
00066 return;
00067
00068 drawStyle = style;
00069 cubicInterpolation = cubic;
00070 }
00071
00073 void PlotMapLabel::setDensityPixmap(const QPixmap& pixmap)
00075 {
00076 if(!densityPixmap)
00077 densityPixmap = new QPixmap(pixmap);
00078 else
00079 *densityPixmap = pixmap;
00080 }
00081
00083 void PlotMapLabel::setCrosses(const vector<Point3D<double> >& centers)
00085 {
00086 if(centers.empty())
00087 return;
00088
00089 crosses.clear();
00090 crosses.reserve(centers.size());
00091 crosses.assign(centers.begin(), centers.end());
00092 }
00093
00095 void PlotMapLabel::setGrid(const Point3D<unsigned int>& pointDimension, const Point3D<double>& pointDelta)
00099 {
00100 numPoints = pointDimension;
00101 delta = pointDelta;
00102 }
00103
00105 void PlotMapLabel::setIsoCurves(const vector< vector<Point3D<double> >* >& curves, const vector<QColor>& lineColors)
00107 {
00108 isoCurves.clear();
00109 isoCurves.reserve(curves.size());
00110 isoCurves.assign(curves.begin(), curves.end());
00111
00112
00113
00114
00115
00116 isoLineColors.clear();
00117 isoLineColors.reserve(lineColors.size());
00118 isoLineColors.assign(lineColors.begin(), lineColors.end());
00119 }
00120
00122 void PlotMapLabel::setPolygons(const vector< vector<Point3D<double> > >& polygons, const vector<QColor>& colors)
00124 {
00125 isoPolygons.clear();
00126 isoPolygons.reserve(polygons.size());
00127 isoPolygons.assign(polygons.begin(), polygons.end());
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 isoPolygonColors.clear();
00138 isoPolygonColors.reserve(colors.size());
00139 isoPolygonColors.assign(colors.begin(), colors.end());
00140 }
00141
00143 void PlotMapLabel::setColors(const QColor& zero, const QColor& atom)
00145 {
00146 zeroColor = zero;
00147 crossColor = atom;
00148 }
00149
00151 void PlotMapLabel::startDrag(const QPoint& pos)
00153 {
00155 if(pos.x() < 0 || pos.y() < 0 || pos.x() > width() || pos.y() > height())
00156 return;
00157
00158 startPosition = pos;
00159 endPosition = pos;
00160 drawDrag = true;
00161 }
00162
00164 void PlotMapLabel::moveDrag(const QPoint& pos)
00166 {
00167 if(!drawDrag)
00168 return;
00169
00170 endPosition = pos;
00171 update();
00172 }
00173
00175 void PlotMapLabel::endDrag()
00177 {
00178 drawDrag = false;
00179 update();
00180 }
00181
00185
00187 void PlotMapLabel::drawContents(QPainter* )
00191 {
00193 const QRect drawRect = contentsRect();
00195
00196
00198 const double aspectRatio = static_cast<double>(numPoints.x()) / numPoints.y();
00199 double scaleX, scaleY;
00200 if(aspectRatio > static_cast<double>(drawRect.width()) / drawRect.height())
00201 {
00202
00203 scaleX = static_cast<double>(drawRect.width()) / numPoints.x();
00204 scaleY = static_cast<double>(drawRect.width()) / aspectRatio / numPoints.y();
00205 }
00206 else
00207 {
00208
00209 scaleX = static_cast<double>(drawRect.height()) * aspectRatio / numPoints.x();
00210 scaleY = static_cast<double>(drawRect.height()) / numPoints.y();
00211 }
00212 const unsigned int maxPoints = static_cast<unsigned int>(scaleX + scaleY);
00213
00215 QPixmap pm(drawRect.width(), drawRect.height());
00216 QPainter paint;
00217 paint.begin(&pm);
00218
00220
00221 paint.fillRect(drawRect, QBrush(zeroColor));
00222 if(drawStyle == 0 && densityPixmap)
00223 {
00224 QRect pixmapRect(drawRect);
00225
00226 if(aspectRatio > static_cast<double>(drawRect.width()) / drawRect.height())
00227 pixmapRect.setHeight(static_cast<int>(drawRect.width() / aspectRatio));
00228 else
00229 pixmapRect.setWidth(static_cast<int>(drawRect.height() * aspectRatio));
00230 paint.drawPixmap(pixmapRect, *densityPixmap);
00231 }
00232
00234 if(false)
00235 {
00236 paint.setPen(QColor(0, 255, 0));
00237 for(unsigned int y = 0; y < numPoints.y(); y++)
00238 {
00239 for(unsigned int x = 0; x < numPoints.x(); x++)
00240 paint.drawPoint(static_cast<int>((x+0.5)*scaleX), static_cast<int>((y+0.5)*scaleY));
00241 }
00242 }
00243
00244 if(drawStyle > 1)
00245 {
00247 for(unsigned int polygon = 0; polygon < isoPolygons.size(); polygon++)
00248 {
00249 paint.setBrush(isoPolygonColors[polygon]);
00250 paint.setPen(Qt::NoPen);
00251 paint.drawPolygon(pointCurve(isoPolygons[polygon], cubicInterpolation, scaleX, scaleY, maxPoints));
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 }
00270 }
00271
00272 if(drawStyle == 1 || drawStyle == 3)
00273 {
00275 if(scaleX <= 1.0 && scaleY <= 1.0)
00276 {
00277
00278 for(unsigned int curve = 0; curve < isoCurves.size(); curve++)
00279 {
00280 paint.setPen(QPen(isoLineColors[curve]));
00281 for(unsigned int i = 0; i < isoCurves[curve]->size() - 1; i++)
00282 {
00283 int x = static_cast<int>((isoCurves[curve]->operator[](i).x()+0.5) * scaleX);
00284 int y = static_cast<int>((isoCurves[curve]->operator[](i).y()+0.5) * scaleY);
00285 paint.drawPoint(x, y);
00286 }
00287 }
00288 }
00289 else
00290 {
00291 for(unsigned int curve = 0; curve < isoCurves.size(); curve++)
00292 {
00293 paint.setPen(QPen(isoLineColors[curve]));
00294 paint.drawPolyline(pointCurve(*isoCurves[curve], cubicInterpolation, scaleX, scaleY, maxPoints));
00295 }
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 }
00364
00366 if(!crosses.empty())
00367 {
00368
00369
00370
00371
00372
00373 scaleX *= 1.0 / delta.x();
00374 scaleY *= 1.0 / delta.y();
00375 paint.setPen(crossColor);
00376 for(unsigned int i = 0; i < crosses.size(); i++)
00377 {
00379 int centerX = static_cast<int>(crosses[i].x()*scaleX);
00380
00381 int centerY = static_cast<int>((numPoints.y()*delta.y() - crosses[i].y())*scaleY);
00382 paint.drawLine(centerX - 5, centerY, centerX + 5, centerY);
00383 paint.drawLine(centerX, centerY - 5, centerX, centerY + 5);
00384 }
00385 }
00386
00388 if(drawDrag)
00389 {
00390
00391
00392 paint.setBrush(Qt::NoBrush);
00393 paint.setPen(QPen(crossColor, 0, Qt::DashLine));
00394 paint.drawRect(QRect(startPosition, endPosition));
00395
00396 }
00397
00399 paint.end();
00400
00402 bitBlt(this, 0, 0, &pm);
00403 }
00404
00408
00410 QPointArray PlotMapLabel::pointCurve(const vector<Point3D<double> >& curve, const bool cubicInterpolation, const double scaleX, const double scaleY, const unsigned int numInterpolated)
00413 {
00414 QPointArray result;
00415
00416 if(cubicInterpolation && curve.size() > 3)
00417 {
00418
00419 for(unsigned int i = 1; i < curve.size() - 2; i++)
00420 {
00421 Point3D<double> controlPoint1((curve[i-1].x()+0.5) * scaleX, (curve[i-1].y()+0.5) * scaleY, 0.0);
00422 Point3D<double> startPoint( (curve[i].x()+0.5) * scaleX, (curve[i].y()+0.5) * scaleY, 0.0);
00423 Point3D<double> endPoint( (curve[i+1].x()+0.5) * scaleX, (curve[i+1].y()+0.5) * scaleY, 0.0);
00424 Point3D<double> controlPoint2((curve[i+2].x()+0.5) * scaleX, (curve[i+2].y()+0.5) * scaleY, 0.0);
00425 if(curve[i-1].x() < Point3D<double>::TOLERANCE && curve[i-1].y() < Point3D<double>::TOLERANCE ||
00426 curve[i].x() < Point3D<double>::TOLERANCE && curve[i].y() < Point3D<double>::TOLERANCE ||
00427 curve[i+1].x() < Point3D<double>::TOLERANCE && curve[i+1].y() < Point3D<double>::TOLERANCE ||
00428 curve[i+2].x() < Point3D<double>::TOLERANCE && curve[i+2].y() < Point3D<double>::TOLERANCE)
00429
00430 result.putPoints(result.size(), 1, static_cast<int>(startPoint.x()), static_cast<int>(startPoint.y()),
00431 static_cast<int>(endPoint.x()), static_cast<int>(endPoint.y()));
00432 else
00433 result.putPoints(result.size(), numInterpolated, cardinalSpline(controlPoint1, startPoint, endPoint, controlPoint2, numInterpolated));
00434 }
00435
00436
00437 const unsigned int lastIndex = curve.size() - 1;
00438 if(curve[0].id() == curve[lastIndex].id())
00439 {
00440
00441 Point3D<double> controlPoint1((curve[lastIndex - 2].x()+0.5) * scaleX, (curve[lastIndex - 2].y()+0.5) * scaleY, 0.0);
00442 Point3D<double> startPoint( (curve[lastIndex - 1].x()+0.5) * scaleX, (curve[lastIndex - 1].y()+0.5) * scaleY, 0.0);
00443 Point3D<double> endPoint( (curve[0].x()+0.5) * scaleX, (curve[0].y()+0.5) * scaleY, 0.0);
00444 Point3D<double> controlPoint2((curve[1].x()+0.5) * scaleX, (curve[1].y()+0.5) * scaleY, 0.0);
00445 if(curve[lastIndex - 2].x() < Point3D<double>::TOLERANCE && curve[lastIndex - 2].y() < Point3D<double>::TOLERANCE ||
00446 curve[lastIndex - 1].x() < Point3D<double>::TOLERANCE && curve[lastIndex - 1].y() < Point3D<double>::TOLERANCE ||
00447 curve[0].x() < Point3D<double>::TOLERANCE && curve[0].y() < Point3D<double>::TOLERANCE ||
00448 curve[1].x() < Point3D<double>::TOLERANCE && curve[1].y() < Point3D<double>::TOLERANCE)
00449
00450 result.putPoints(result.size(), 1, static_cast<int>(startPoint.x()), static_cast<int>(startPoint.y()),
00451 static_cast<int>(endPoint.x()), static_cast<int>(endPoint.y()));
00452 else
00453 result.putPoints(result.size(), numInterpolated, cardinalSpline(controlPoint1, startPoint, endPoint, controlPoint2, numInterpolated));
00454
00455 controlPoint1 = startPoint;
00456 startPoint = endPoint;
00457 endPoint = controlPoint2;
00458 controlPoint2.setValues((curve[2].x()+0.5) * scaleX, (curve[2].y()+0.5) * scaleY, 0.0);
00459 if(curve[lastIndex - 1].x() < Point3D<double>::TOLERANCE && curve[lastIndex - 1].y() < Point3D<double>::TOLERANCE ||
00460 curve[0].x() < Point3D<double>::TOLERANCE && curve[0].y() < Point3D<double>::TOLERANCE ||
00461 curve[1].x() < Point3D<double>::TOLERANCE && curve[1].y() < Point3D<double>::TOLERANCE ||
00462 curve[2].x() < Point3D<double>::TOLERANCE && curve[2].y() < Point3D<double>::TOLERANCE)
00463
00464 result.putPoints(result.size(), 1, static_cast<int>(startPoint.x()), static_cast<int>(startPoint.y()),
00465 static_cast<int>(endPoint.x()), static_cast<int>(endPoint.y()));
00466 else
00467 result.putPoints(result.size(), numInterpolated, cardinalSpline(controlPoint1, startPoint, endPoint, controlPoint2, numInterpolated));
00468 }
00469 }
00470 else if(curve.size() > 1)
00471 {
00472
00473 result.resize(curve.size());
00474 for(unsigned int i = 0; i < curve.size(); i++)
00475 result.setPoint(i, static_cast<int>((curve[i].x()+0.5) * scaleX), static_cast<int>((curve[i].y()+0.5) * scaleY));
00476 }
00477 return result;
00478 }
00479
00481 QPointArray PlotMapLabel::cardinalSpline(const Point3D<double>& controlPoint1, const Point3D<double>& startPoint, const Point3D<double>& endPoint, const Point3D<double>& controlPoint2, const unsigned int numInterpolated)
00485 {
00486 const double t = 0.0;
00487
00488 const double s = (1.0 - t)/2.0;
00489
00490
00491
00492 QPointArray result(numInterpolated);
00493
00494 for(unsigned int i = 0; i < numInterpolated; i++)
00495 {
00496 const double value = static_cast<double>(i)/numInterpolated;
00497 const double value2 = value*value;
00498 const double value3 = value2*value;
00499 const int x = static_cast<int>( ( -s*controlPoint1.x() + (2.0 - s)*startPoint.x() + (s - 2.0)*endPoint.x() + s*controlPoint2.x() ) * value3
00500 + ( 2.0*s*controlPoint1.x() + (s - 3.0)*startPoint.x() + (3.0 - 2.0*s)*endPoint.x() - s*controlPoint2.x() ) * value2
00501 + ( -s*controlPoint1.x() + s*endPoint.x() ) * value
00502 + startPoint.x()
00503 );
00504 const int y = static_cast<int>( ( -s*controlPoint1.y() + (2.0 - s)*startPoint.y() + (s - 2.0)*endPoint.y() + s*controlPoint2.y() ) * value3
00505 + ( 2.0*s*controlPoint1.y() + (s - 3.0)*startPoint.y() + (3.0 - 2.0*s)*endPoint.y() - s*controlPoint2.y() ) * value2
00506 + ( -s*controlPoint1.y() + s*endPoint.y() ) * value
00507 + startPoint.y()
00508 );
00509 result.setPoint(i, x, y);
00510
00511
00512
00513
00514
00515
00516
00517 }
00518 return result;
00519 }
00520