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