Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

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 
00013 #if QT_VERSION < 0x040000
00014 #define QwtPointArray QPointArray
00015 #else
00016 #define QwtPointArray QPolygon
00017 #endif
00018 
00020 
00021 QwtRect::QwtRect(): 
00022     QRect() 
00023 {
00024 }
00025 
00027 QwtRect::QwtRect(const QRect &r): 
00028     QRect(r) 
00029 {
00030 }
00031 
00032 QRect QwtRect::cutTop(int h, int distTop, int distBottom)
00033 {
00034     QRect rv;
00035     rv.setTop(top() + distTop);
00036     rv.setHeight(h);
00037     setTop(rv.bottom() + distBottom + 1);
00038     rv.setLeft(left());
00039     rv.setRight(right());
00040     return rv;
00041 }
00042 
00043 QRect QwtRect::cutBottom(int h, int distTop, int distBottom)
00044 {
00045     QRect rv;
00046     setBottom(bottom() - h - distBottom - distTop);
00047     rv.setTop(bottom() + 1 + distTop);
00048     rv.setHeight(h);
00049     rv.setLeft(left());
00050     rv.setRight(right());
00051     return rv;
00052 }
00053 
00054 QRect QwtRect::cutLeft(int w, int distLeft, int distRight)
00055 {
00056     QRect rv;
00057     rv.setLeft(left() + distLeft);
00058     rv.setWidth(w);
00059     setLeft(rv.right() + distRight + 1);
00060     rv.setTop(top());
00061     rv.setBottom(bottom());
00062     return rv;
00063 }
00064 
00065 QRect QwtRect::cutRight(int w, int distLeft, int distRight)
00066 {
00067     QRect rv;
00068     setRight(right() - w - distRight - distLeft);
00069     rv.setLeft(right() + 1 + distLeft);
00070     rv.setWidth(w);
00071     rv.setTop(top());
00072     rv.setBottom(bottom());
00073     return rv;
00074 }
00075 
00076 const QwtRect& QwtRect::cutMargin(int mLeft, int mRight, int mTop, int mBottom)
00077 {
00078     setHeight(height() - mTop - mBottom);
00079     setWidth(width() - mLeft - mRight);
00080 #if QT_VERSION < 0x040000
00081     moveBy(mLeft, mTop);
00082 #else
00083     translate(mLeft, mTop);
00084 #endif
00085     return *this;
00086 }
00087 
00088 inline void addPoint(QwtPointArray &pa, uint pos, const QPoint &point)
00089 {
00090     if ( uint(pa.size()) <= pos ) 
00091         pa.resize(pos + 5);
00092 
00093     pa.setPoint(pos, point);
00094 }
00095 
00097 
00098 QwtPointArray QwtRect::clip(const QwtPointArray &pa) const
00099 {
00100     if ( contains( pa.boundingRect() ) )
00101         return pa;
00102 
00103     QwtPointArray cpa(pa.size());
00104 
00105     clipEdge((Edge)0, pa, cpa);
00106 
00107     for ( uint edge = 1; edge < NEdges; edge++ ) 
00108     {
00109         const QwtPointArray rpa = cpa;
00110 #if QT_VERSION < 0x040000
00111         cpa.detach();
00112 #endif
00113         clipEdge((Edge)edge, rpa, cpa);
00114     }
00115 
00116     return cpa;
00117 }
00118 
00119 bool QwtRect::insideEdge(const QPoint &p, Edge edge) const
00120 {
00121     switch(edge) 
00122     {
00123         case Left:
00124             return p.x() > left();
00125         case Top:
00126             return p.y() > top();
00127         case Right:
00128             return p.x() < right();
00129         case Bottom:
00130             return p.y() < bottom();
00131         default:
00132             break;
00133     }
00134 
00135     return false;
00136 }
00137 
00138 QPoint QwtRect::intersectEdge(const QPoint &p1, 
00139     const QPoint &p2, Edge edge ) const
00140 {
00141     int x=0, y=0;
00142     double m = 0;
00143 
00144     const double dy = p2.y() - p1.y();
00145     const double dx = p2.x() - p1.x();
00146 
00147     switch ( edge ) 
00148     {
00149         case Left:
00150             x = left();
00151             m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
00152             y = p1.y() + int(dy * m);
00153             break;
00154         case Top:
00155             y = top();
00156             m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
00157             x = p1.x() + int(dx * m);
00158             break;
00159         case Right:
00160             x = right();
00161             m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
00162             y = p1.y() + int(dy * m);
00163             break;
00164         case Bottom:
00165             y = bottom();
00166             m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
00167             x = p1.x() + int(dx * m);
00168             break;
00169         default:
00170             break;
00171     }
00172 
00173     return QPoint(x,y);
00174 }
00175 
00176 void QwtRect::clipEdge(Edge edge, 
00177     const QwtPointArray &pa, QwtPointArray &cpa) const
00178 {
00179     if ( pa.count() == 0 )
00180     {
00181         cpa.resize(0);
00182         return;
00183     }
00184 
00185     unsigned int count = 0;
00186 
00187     QPoint p1 = pa.point(0);
00188     if ( insideEdge(p1, edge) )
00189         addPoint(cpa, count++, p1);
00190 
00191     const uint nPoints = pa.size();
00192     for ( uint i = 1; i < nPoints; i++ )
00193     {
00194         const QPoint p2 = pa.point(i);
00195         if ( insideEdge(p2, edge) )
00196         {
00197             if ( insideEdge(p1, edge) )
00198                 addPoint(cpa, count++, p2);
00199             else
00200             {
00201                 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00202                 addPoint(cpa, count++, p2);
00203             }
00204         }
00205         else
00206         {
00207             if ( insideEdge(p1, edge) )
00208                 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00209         }
00210         p1 = p2;
00211     }
00212     cpa.resize(count);
00213 }

Generated on Wed Aug 31 23:02:29 2005 for Qwt User's Guide by  doxygen 1.4.1