00001
00002
00003
00004
00005
00006
00007
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 }