qwt_rect.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_math.h"
00011 #include "qwt_rect.h"
00012 
00014 
00015 QwtRect::QwtRect(): 
00016     QRect() 
00017 {
00018 }
00019 
00021 QwtRect::QwtRect(const QRect &r): 
00022     QRect(r) 
00023 {
00024 }
00025 
00026 inline static void addPoint(QwtPolygon &pa, uint pos, const QPoint &point)
00027 {
00028     if ( uint(pa.size()) <= pos ) 
00029         pa.resize(pos + 5);
00030 
00031     pa.setPoint(pos, point);
00032 }
00033 
00035 
00036 QwtPolygon QwtRect::clip(const QwtPolygon &pa) const
00037 {
00038     if ( contains( pa.boundingRect() ) )
00039         return pa;
00040 
00041     QwtPolygon cpa(pa.size());
00042 
00043     clipEdge((Edge)0, pa, cpa);
00044 
00045     for ( uint edge = 1; edge < NEdges; edge++ ) 
00046     {
00047         const QwtPolygon rpa = cpa;
00048 #if QT_VERSION < 0x040000
00049         cpa.detach();
00050 #endif
00051         clipEdge((Edge)edge, rpa, cpa);
00052     }
00053 
00054     return cpa;
00055 }
00056 
00057 bool QwtRect::insideEdge(const QPoint &p, Edge edge) const
00058 {
00059     switch(edge) 
00060     {
00061         case Left:
00062             return p.x() > left();
00063         case Top:
00064             return p.y() > top();
00065         case Right:
00066             return p.x() < right();
00067         case Bottom:
00068             return p.y() < bottom();
00069         default:
00070             break;
00071     }
00072 
00073     return false;
00074 }
00075 
00076 QPoint QwtRect::intersectEdge(const QPoint &p1, 
00077     const QPoint &p2, Edge edge ) const
00078 {
00079     int x=0, y=0;
00080     double m = 0;
00081 
00082     const double dy = p2.y() - p1.y();
00083     const double dx = p2.x() - p1.x();
00084 
00085     switch ( edge ) 
00086     {
00087         case Left:
00088             x = left();
00089             m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
00090             y = p1.y() + int(dy * m);
00091             break;
00092         case Top:
00093             y = top();
00094             m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
00095             x = p1.x() + int(dx * m);
00096             break;
00097         case Right:
00098             x = right();
00099             m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
00100             y = p1.y() + int(dy * m);
00101             break;
00102         case Bottom:
00103             y = bottom();
00104             m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
00105             x = p1.x() + int(dx * m);
00106             break;
00107         default:
00108             break;
00109     }
00110 
00111     return QPoint(x,y);
00112 }
00113 
00114 void QwtRect::clipEdge(Edge edge, 
00115     const QwtPolygon &pa, QwtPolygon &cpa) const
00116 {
00117     if ( pa.count() == 0 )
00118     {
00119         cpa.resize(0);
00120         return;
00121     }
00122 
00123     unsigned int count = 0;
00124 
00125     QPoint p1 = pa.point(0);
00126     if ( insideEdge(p1, edge) )
00127         addPoint(cpa, count++, p1);
00128 
00129     const uint nPoints = pa.size();
00130     for ( uint i = 1; i < nPoints; i++ )
00131     {
00132         const QPoint p2 = pa.point(i);
00133         if ( insideEdge(p2, edge) )
00134         {
00135             if ( insideEdge(p1, edge) )
00136                 addPoint(cpa, count++, p2);
00137             else
00138             {
00139                 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00140                 addPoint(cpa, count++, p2);
00141             }
00142         }
00143         else
00144         {
00145             if ( insideEdge(p1, edge) )
00146                 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00147         }
00148         p1 = p2;
00149     }
00150     cpa.resize(count);
00151 }

Generated on Mon Feb 26 21:22:38 2007 for Qwt User's Guide by  doxygen 1.4.6