95 static const double SMALL_NUM;
109 static bool inside(
const double x,
const double y,
Boundary b );
115 static QgsPoint intersect(
const double x1,
const double y1,
116 const double x2,
const double y2,
124 static bool clipLineSegment(
double xLeft,
double xRight,
double yBottom,
double yTop,
double& x0,
double& y0,
double& x1,
double& y1 );
134 static void connectSeparatedLines(
double x0,
double y0,
double x1,
double y1,
138 static void clipStartTop(
double& x0,
double& y0,
double x1,
double y1,
double yMax );
139 static void clipStartBottom(
double& x0,
double& y0,
double x1,
double y1,
double yMin );
140 static void clipStartRight(
double& x0,
double& y0,
double x1,
double y1,
double xMax );
141 static void clipStartLeft(
double& x0,
double& y0,
double& x1,
double& y1,
double xMin );
142 static void clipEndTop(
double x0,
double y0,
double& x1,
double& y1,
double yMax );
143 static void clipEndBottom(
double x0,
double y0,
double& x1,
double& y1,
double yMin );
144 static void clipEndRight(
double x0,
double y0,
double& x1,
double& y1,
double xMax );
145 static void clipEndLeft(
double x0,
double y0,
double& x1,
double& y1,
double xMin );
166 trimFeatureToBoundary( x, y, tmpX, tmpY, XMax, shapeOpen );
170 trimFeatureToBoundary( tmpX, tmpY, x, y, YMax, shapeOpen );
174 trimFeatureToBoundary( x, y, tmpX, tmpY, XMin, shapeOpen );
178 trimFeatureToBoundary( tmpX, tmpY, x, y, YMin, shapeOpen );
186 trimPolygonToBoundary( pts, tmpPts, clipRect, XMax, clipRect.
xMaximum() );
188 trimPolygonToBoundary( tmpPts, pts, clipRect, YMax, clipRect.
yMaximum() );
190 trimPolygonToBoundary( pts, tmpPts, clipRect, XMin, clipRect.
xMinimum() );
192 trimPolygonToBoundary( tmpPts, pts, clipRect, YMin, clipRect.
yMinimum() );
200 inline void QgsClipper::trimFeatureToBoundary(
211 int i1 = inX.
size() - 1;
214 for (
int i2 = 0; i2 < inX.
size() ; ++i2 )
219 if ( qIsNaN( inX[i2] ) || qIsNaN( inY[i2] ) || qIsInf( inX[i2] ) || qIsInf( inY[i2] )
220 || qIsNaN( inX[i1] ) || qIsNaN( inY[i1] ) || qIsInf( inX[i1] ) || qIsInf( inY[i1] ) )
227 if ( inside( inX[i2], inY[i2], b ) )
229 if ( inside( inX[i1], inY[i1], b ) )
238 if ( !( i2 == 0 && shapeOpen ) )
240 QgsPoint p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
252 if ( inside( inX[i1], inY[i1], b ) )
254 if ( !( i2 == 0 && shapeOpen ) )
256 QgsPoint p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
268 int i1 = inPts.
size() - 1;
271 for (
int i2 = 0; i2 < inPts.
size() ; ++i2 )
273 if ( inside( inPts[i2], b, boundaryValue ) )
275 if ( inside( inPts[i1], b, boundaryValue ) )
277 outPts.
append( inPts[i2] );
283 outPts.
append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
284 outPts.
append( inPts[i2] );
290 if ( inside( inPts[i1], b, boundaryValue ) )
292 outPts.
append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
302 inline bool QgsClipper::inside(
const double x,
const double y,
Boundary b )
331 return ( pt.
x() < val );
333 return ( pt.
x() > val );
335 return ( pt.
y() < val );
337 return ( pt.
y() > val );
347 inline QgsPoint QgsClipper::intersect(
const double x1,
const double y1,
348 const double x2,
const double y2,
355 double r_n = SMALL_NUM, r_d = SMALL_NUM;
360 r_n = -( x1 - MAX_X ) * ( MAX_Y - MIN_Y );
361 r_d = ( x2 - x1 ) * ( MAX_Y - MIN_Y );
364 r_n = -( x1 - MIN_X ) * ( MAX_Y - MIN_Y );
365 r_d = ( x2 - x1 ) * ( MAX_Y - MIN_Y );
368 r_n = ( y1 - MAX_Y ) * ( MAX_X - MIN_X );
369 r_d = -( y2 - y1 ) * ( MAX_X - MIN_X );
372 r_n = ( y1 - MIN_Y ) * ( MAX_X - MIN_X );
373 r_d = -( y2 - y1 ) * ( MAX_X - MIN_X );
379 if ( qAbs( r_d ) > SMALL_NUM && qAbs( r_n ) > SMALL_NUM )
381 double r = r_n / r_d;
382 p.
set( x1 + r*( x2 - x1 ), y1 + r*( y2 - y1 ) );
388 Q_ASSERT( qAbs( r_d ) > SMALL_NUM && qAbs( r_n ) > SMALL_NUM );
402 double r_n = SMALL_NUM, r_d = SMALL_NUM;
403 const double x1 = pt1.
x(), x2 = pt2.
x();
404 const double y1 = pt1.
y(), y2 = pt2.
y();
431 return QPointF( x1 + r*( x2 - x1 ), y1 + r*( y2 - y1 ) );
434 inline void QgsClipper::clipStartTop(
double& x0,
double& y0,
double x1,
double y1,
double yMax )
436 x0 += ( x1 - x0 ) * ( yMax - y0 ) / ( y1 - y0 );
440 inline void QgsClipper::clipStartBottom(
double& x0,
double& y0,
double x1,
double y1,
double yMin )
442 x0 += ( x1 - x0 ) * ( yMin - y0 ) / ( y1 - y0 );
446 inline void QgsClipper::clipStartRight(
double& x0,
double& y0,
double x1,
double y1,
double xMax )
448 y0 += ( y1 - y0 ) * ( xMax - x0 ) / ( x1 - x0 );
452 inline void QgsClipper::clipStartLeft(
double& x0,
double& y0,
double& x1,
double& y1,
double xMin )
454 y0 += ( y1 - y0 ) * ( xMin - x0 ) / ( x1 - x0 );
458 inline void QgsClipper::clipEndTop(
double x0,
double y0,
double& x1,
double& y1,
double yMax )
460 x1 += ( x1 - x0 ) * ( yMax - y1 ) / ( y1 - y0 );
464 inline void QgsClipper::clipEndBottom(
double x0,
double y0,
double& x1,
double& y1,
double yMin )
466 x1 += ( x1 - x0 ) * ( yMin - y1 ) / ( y1 - y0 );
470 inline void QgsClipper::clipEndRight(
double x0,
double y0,
double& x1,
double& y1,
double xMax )
472 y1 += ( y1 - y0 ) * ( xMax - x1 ) / ( x1 - x0 );
476 inline void QgsClipper::clipEndLeft(
double x0,
double y0,
double& x1,
double& y1,
double xMin )
478 y1 += ( y1 - y0 ) * ( xMin - x1 ) / ( x1 - x0 );
483 inline bool QgsClipper::clipLineSegment(
double xLeft,
double xRight,
double yBottom,
double yTop,
double& x0,
double& y0,
double& x1,
double& y1 )
489 else if ( y1 > yTop )
494 else if ( x1 < xLeft )
499 else if ( y0 > yTop )
504 else if ( x0 < xLeft )
513 clipEndLeft( x0, y0, x1, y1, xLeft );
517 clipEndRight( x0, y0, x1, y1, xRight );
521 clipEndBottom( x0, y0, x1, y1, yBottom );
525 clipEndLeft( x0, y0, x1, y1, xLeft );
527 clipEndBottom( x0, y0, x1, y1, yBottom );
531 clipEndRight( x0, y0, x1, y1, xRight );
533 clipEndBottom( x0, y0, x1, y1, yBottom );
537 clipEndTop( x0, y0, x1, y1, yTop );
541 clipEndLeft( x0, y0, x1, y1, xLeft );
543 clipEndTop( x0, y0, x1, y1, yTop );
547 clipEndRight( x0, y0, x1, y1, xRight );
549 clipEndTop( x0, y0, x1, y1, yTop );
553 clipStartLeft( x0, y0, x1, y1, xLeft );
557 clipStartLeft( x0, y0, x1, y1, xLeft );
558 clipEndRight( x0, y0, x1, y1, xRight );
562 clipStartLeft( x0, y0, x1, y1, xLeft );
565 clipEndBottom( x0, y0, x1, y1, yBottom );
569 clipStartLeft( x0, y0, x1, y1, xLeft );
572 clipEndBottom( x0, y0, x1, y1, yBottom );
574 clipEndRight( x0, y0, x1, y1, xRight );
578 clipStartLeft( x0, y0, x1, y1, xLeft );
581 clipEndTop( x0, y0, x1, y1, yTop );
585 clipStartLeft( x0, y0, x1, y1, xLeft );
588 clipEndTop( x0, y0, x1, y1, yTop );
590 clipEndRight( x0, y0, x1, y1, xRight );
594 clipStartRight( x0, y0, x1, y1, xRight );
598 clipStartRight( x0, y0, x1, y1, xRight );
599 clipEndLeft( x0, y0, x1, y1, xLeft );
603 clipStartRight( x0, y0, x1, y1, xRight );
606 clipEndBottom( x0, y0, x1, y1, yBottom );
610 clipStartRight( x0, y0, x1, y1, xRight );
613 clipEndBottom( x0, y0, x1, y1, yBottom );
615 clipEndLeft( x0, y0, x1, y1, xLeft );
619 clipStartRight( x0, y0, x1, y1, xRight );
622 clipEndTop( x0, y0, x1, y1, yTop );
626 clipStartRight( x0, y0, x1, y1, xRight );
629 clipEndTop( x0, y0, x1, y1, yTop );
631 clipEndLeft( x0, y0, x1, y1, xLeft );
635 clipStartBottom( x0, y0, x1, y1, yBottom );
639 clipStartBottom( x0, y0, x1, y1, yBottom );
642 clipEndLeft( x0, y0, x1, y1, xLeft );
644 clipEndBottom( x0, y0, x1, y1, yBottom );
648 clipStartBottom( x0, y0, x1, y1, yBottom );
651 clipEndRight( x0, y0, x1, y1, xRight );
655 clipStartBottom( x0, y0, x1, y1, yBottom );
656 clipEndTop( x0, y0, x1, y1, yTop );
660 clipStartBottom( x0, y0, x1, y1, yBottom );
663 clipEndLeft( x0, y0, x1, y1, xLeft );
665 clipEndTop( x0, y0, x1, y1, yTop );
669 clipStartBottom( x0, y0, x1, y1, yBottom );
672 clipEndRight( x0, y0, x1, y1, xRight );
674 clipEndTop( x0, y0, x1, y1, yTop );
678 clipStartLeft( x0, y0, x1, y1, xLeft );
680 clipStartBottom( x0, y0, x1, y1, yBottom );
684 clipEndRight( x0, y0, x1, y1, xRight );
687 clipStartBottom( x0, y0, x1, y1, yBottom );
689 clipStartLeft( x0, y0, x1, y1, xLeft );
693 clipEndTop( x0, y0, x1, y1, yTop );
696 clipStartBottom( x0, y0, x1, y1, yBottom );
698 clipStartLeft( x0, y0, x1, y1, xLeft );
702 clipStartLeft( x0, y0, x1, y1, xLeft );
705 clipEndRight( x0, y0, x1, y1, xRight );
709 clipStartBottom( x0, y0, x1, y1, yBottom );
711 clipEndTop( x0, y0, x1, y1, yTop );
715 clipStartRight( x0, y0, x1, y1, xRight );
717 clipStartBottom( x0, y0, x1, y1, yBottom );
721 clipEndLeft( x0, y0, x1, y1, xLeft );
724 clipStartBottom( x0, y0, x1, y1, yBottom );
726 clipStartRight( x0, y0, x1, y1, xRight );
730 clipEndTop( x0, y0, x1, y1, yTop );
733 clipStartRight( x0, y0, x1, y1, xRight );
735 clipStartBottom( x0, y0, x1, y1, yBottom );
739 clipEndLeft( x0, y0, x1, y1, xLeft );
742 clipStartRight( x0, y0, x1, y1, xRight );
746 clipEndTop( x0, y0, x1, y1, yTop );
748 clipStartBottom( x0, y0, x1, y1, yBottom );
752 clipStartTop( x0, y0, x1, y1, yTop );
756 clipStartTop( x0, y0, x1, y1, yTop );
759 clipEndLeft( x0, y0, x1, y1, xLeft );
763 clipStartTop( x0, y0, x1, y1, yTop );
766 clipEndRight( x0, y0, x1, y1, xRight );
770 clipStartTop( x0, y0, x1, y1, yTop );
771 clipEndBottom( x0, y0, x1, y1, yBottom );
775 clipStartTop( x0, y0, x1, y1, yTop );
778 clipEndLeft( x0, y0, x1, y1, xLeft );
780 clipEndBottom( x0, y0, x1, y1, yBottom );
784 clipStartTop( x0, y0, x1, y1, yTop );
787 clipEndRight( x0, y0, x1, y1, xRight );
789 clipEndBottom( x0, y0, x1, y1, yBottom );
793 clipStartLeft( x0, y0, x1, y1, xLeft );
795 clipStartTop( x0, y0, x1, y1, yTop );
799 clipEndRight( x0, y0, x1, y1, xRight );
802 clipStartTop( x0, y0, x1, y1, yTop );
804 clipStartLeft( x0, y0, x1, y1, xLeft );
808 clipEndBottom( x0, y0, x1, y1, yBottom );
811 clipStartLeft( x0, y0, x1, y1, xLeft );
813 clipStartTop( x0, y0, x1, y1, yTop );
817 clipStartLeft( x0, y0, x1, y1, xLeft );
820 clipEndRight( x0, y0, x1, y1, xRight );
824 clipStartTop( x0, y0, x1, y1, yTop );
826 clipEndBottom( x0, y0, x1, y1, yBottom );
830 clipStartRight( x0, y0, x1, y1, xRight );
832 clipStartTop( x0, y0, x1, y1, yTop );
836 clipEndLeft( x0, y0, x1, y1, xLeft );
839 clipStartTop( x0, y0, x1, y1, yTop );
841 clipStartRight( x0, y0, x1, y1, xRight );
845 clipEndBottom( x0, y0, x1, y1, yBottom );
848 clipStartRight( x0, y0, x1, y1, xRight );
850 clipStartTop( x0, y0, x1, y1, yTop );
854 clipEndLeft( x0, y0, x1, y1, xLeft );
857 clipStartRight( x0, y0, x1, y1, xRight );
861 clipEndBottom( x0, y0, x1, y1, yBottom );
863 clipStartTop( x0, y0, x1, y1, yTop );
static const double MAX_Y
A rectangle specified with double values.
static void trimFeature(QVector< double > &x, QVector< double > &y, bool shapeOpen)
Trims the given feature to a rectangular box.
void append(const T &value)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
double y() const
Get the y value of the point.
static const double MIN_X
A class to trim lines and polygons to within a rectangular region.
void set(double x, double y)
Sets the x and y value of the point.
A class to represent a point.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
Boundary
A handy way to refer to the four boundaries.
double xMinimum() const
Get the x minimum value (left side of rectangle)
void push_back(const T &value)
double yMaximum() const
Get the y maximum value (top side of rectangle)
static const double MIN_Y
static void trimPolygon(QPolygonF &pts, const QgsRectangle &clipRect)
static const double MAX_X
double x() const
Get the x value of the point.