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 inline static void addPoint(QwtPointArray &pa, uint pos, const QPoint &point)
00033 {
00034     if ( uint(pa.size()) <= pos ) 
00035         pa.resize(pos + 5);
00036 
00037     pa.setPoint(pos, point);
00038 }
00039 
00041 
00042 QwtPointArray QwtRect::clip(const QwtPointArray &pa) const
00043 {
00044     if ( contains( pa.boundingRect() ) )
00045         return pa;
00046 
00047     QwtPointArray cpa(pa.size());
00048 
00049     clipEdge((Edge)0, pa, cpa);
00050 
00051     for ( uint edge = 1; edge < NEdges; edge++ ) 
00052     {
00053         const QwtPointArray rpa = cpa;
00054 #if QT_VERSION < 0x040000
00055         cpa.detach();
00056 #endif
00057         clipEdge((Edge)edge, rpa, cpa);
00058     }
00059 
00060     return cpa;
00061 }
00062 
00063 bool QwtRect::insideEdge(const QPoint &p, Edge edge) const
00064 {
00065     switch(edge) 
00066     {
00067         case Left:
00068             return p.x() > left();
00069         case Top:
00070             return p.y() > top();
00071         case Right:
00072             return p.x() < right();
00073         case Bottom:
00074             return p.y() < bottom();
00075         default:
00076             break;
00077     }
00078 
00079     return false;
00080 }
00081 
00082 QPoint QwtRect::intersectEdge(const QPoint &p1, 
00083     const QPoint &p2, Edge edge ) const
00084 {
00085     int x=0, y=0;
00086     double m = 0;
00087 
00088     const double dy = p2.y() - p1.y();
00089     const double dx = p2.x() - p1.x();
00090 
00091     switch ( edge ) 
00092     {
00093         case Left:
00094             x = left();
00095             m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
00096             y = p1.y() + int(dy * m);
00097             break;
00098         case Top:
00099             y = top();
00100             m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
00101             x = p1.x() + int(dx * m);
00102             break;
00103         case Right:
00104             x = right();
00105             m = double(qwtAbs(p1.x() - x)) / qwtAbs(dx);
00106             y = p1.y() + int(dy * m);
00107             break;
00108         case Bottom:
00109             y = bottom();
00110             m = double(qwtAbs(p1.y() - y)) / qwtAbs(dy);
00111             x = p1.x() + int(dx * m);
00112             break;
00113         default:
00114             break;
00115     }
00116 
00117     return QPoint(x,y);
00118 }
00119 
00120 void QwtRect::clipEdge(Edge edge, 
00121     const QwtPointArray &pa, QwtPointArray &cpa) const
00122 {
00123     if ( pa.count() == 0 )
00124     {
00125         cpa.resize(0);
00126         return;
00127     }
00128 
00129     unsigned int count = 0;
00130 
00131     QPoint p1 = pa.point(0);
00132     if ( insideEdge(p1, edge) )
00133         addPoint(cpa, count++, p1);
00134 
00135     const uint nPoints = pa.size();
00136     for ( uint i = 1; i < nPoints; i++ )
00137     {
00138         const QPoint p2 = pa.point(i);
00139         if ( insideEdge(p2, edge) )
00140         {
00141             if ( insideEdge(p1, edge) )
00142                 addPoint(cpa, count++, p2);
00143             else
00144             {
00145                 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00146                 addPoint(cpa, count++, p2);
00147             }
00148         }
00149         else
00150         {
00151             if ( insideEdge(p1, edge) )
00152                 addPoint(cpa, count++, intersectEdge(p1, p2, edge));
00153         }
00154         p1 = p2;
00155     }
00156     cpa.resize(count);
00157 }

Generated on Mon Jan 30 22:16:26 2006 for Qwt User's Guide by  doxygen 1.4.4