40 void heapsort( 
int *sid, 
int *
id, 
const std::vector< double > &x, 
int N )
 
   42   unsigned int n = N, i = n / 2, parent, child;
 
   62       if ( child + 1 < n  &&  x[
id[sid[child + 1]]] > x[
id[sid[child]]] )
 
   66       if ( x[
id[sid[child]]] > x[
id[tx]] )
 
   68         sid[parent] = sid[child];
 
   70         child = parent * 2 + 1;
 
   84   unsigned int n = N, i = n / 2, parent, child;
 
  108       if ( child + 1 < n  &&  heap[child + 1] > heap[child] )
 
  112       if ( heap[child] > t )
 
  114         heap[parent] = heap[child];
 
  115         x[parent] = x[child];
 
  117         child = parent * 2 + 1;
 
  130                                     double x3, 
double y3, 
double x4, 
double y4 )  
 
  132   return ( 
cross_product( x1, y1, x2, y2, x3, y3 ) * 
cross_product( x1, y1, x2, y2, x4, y4 ) < 0
 
  133            && 
cross_product( x3, y3, x4, y4, x1, y1 ) * 
cross_product( x3, y3, x4, y4, x2, y2 ) < 0 );
 
  137     double x3, 
double y3, 
double x4, 
double y4,  
 
  138     double *x, 
double *y )
 
  141   double a1, a2, b1, b2, c1, c2;
 
  146   c1 = x2 * y1 - x1 * y2;
 
  150   c2 = x4 * y3 - x3 * y4;
 
  152   denom = a1 * b2 - a2 * b1;
 
  159     *x = ( b1 * c2 - b2 * c1 ) / denom;
 
  160     *y = ( a2 * c1 - a1 * c2 ) / denom;
 
  171   for ( i = 0; i < n; i++ )
 
  177   if ( n <= 3 ) 
return n;
 
  179   int *stack = 
new int[n];
 
  180   double *tan = 
new double [n];
 
  191   while ( ref < n && 
qgsDoubleNear( y[
id[cHull[ref]]], y[
id[cHull[0]]] ) ) ref++;
 
  196   for ( i = ref; i < n; i++ )
 
  201       tan[i] = ( x[
id[cHull[0]]] - x[
id[cHull[i]]] ) / ( y[
id[cHull[i]]] - y[
id[cHull[0]]] );
 
  205     heapsort2( cHull + ref, tan + ref, n - ref );
 
  215     stack[1] = cHull[ref - 1];
 
  221   for ( i = ref; i < n; i++ )
 
  223     result = 
cross_product( x[
id[stack[second]]], y[
id[stack[second]]],
 
  224                             x[
id[stack[top]]], y[
id[stack[top]]], x[
id[cHull[i]]], y[
id[cHull[i]]] );
 
  228       if ( 
dist_euc2d_sq( x[
id[stack[second]]], y[
id[stack[second]]], x[
id[cHull[i]]], y[
id[cHull[i]]] )
 
  229            >  
dist_euc2d_sq( x[
id[stack[second]]], y[
id[stack[second]]], x[
id[stack[top]]], y[
id[stack[top]]] ) )
 
  231         stack[top] = cHull[i];
 
  234     else if ( result > 0 ) 
 
  238       stack[top] = cHull[i];
 
  242       while ( result < 0 && top > 1 )
 
  247                                 y[
id[stack[second]]], x[
id[stack[top]]],
 
  248                                 y[
id[stack[top]]], x[
id[cHull[i]]], y[
id[cHull[i]]] );
 
  252       stack[top] = cHull[i];
 
  256   for ( i = 0; i <= top; i++ )
 
  270   int *cHull = 
nullptr;
 
  273   int *pts = 
new int[nbPoints];
 
  274   for ( i = 0; i < nbPoints; i++ )
 
  279   if ( pts[cHull[0]] < pts[cHull[1]] && pts[cHull[1]] < pts[cHull[2]] )
 
  281   else if ( pts[cHull[0]] > pts[cHull[1]] && pts[cHull[1]] > pts[cHull[2]] )
 
  283   else if ( pts[cHull[0]] > pts[cHull[1]] && pts[cHull[1]] < pts[cHull[2]] && pts[cHull[2]] < pts[cHull[0]] )
 
  285   else if ( pts[cHull[0]] > pts[cHull[1]] && pts[cHull[1]] < pts[cHull[2]] && pts[cHull[2]] > pts[cHull[0]] )
 
  287   else if ( pts[cHull[0]] < pts[cHull[1]] && pts[cHull[1]] > pts[cHull[2]] && pts[cHull[2]] > pts[cHull[0]] )
 
  289   else if ( pts[cHull[0]] < pts[cHull[1]] && pts[cHull[1]] > pts[cHull[2]] && pts[cHull[2]] < pts[cHull[0]] )
 
  303     for ( i = 0, j = nbPoints - 1; i <= j; i++, j-- )
 
  329     GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 5, 2 );
 
  331 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  332     GEOSCoordSeq_setXY_r( geosctxt, coord, 0, x, y );
 
  334     GEOSCoordSeq_setX_r( geosctxt, coord, 0, x );
 
  335     GEOSCoordSeq_setY_r( geosctxt, coord, 0, y );
 
  339       double beta = alpha + M_PI_2;
 
  340       double dx1 = std::cos( alpha ) * width;
 
  341       double dy1 = std::sin( alpha ) * width;
 
  342       double dx2 = std::cos( beta ) * height;
 
  343       double dy2 = std::sin( beta ) * height;
 
  344 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  345       GEOSCoordSeq_setXY_r( geosctxt, coord, 1, x  + dx1, y + dy1 );
 
  346       GEOSCoordSeq_setXY_r( geosctxt, coord, 2, x + dx1 + dx2, y + dy1 + dy2 );
 
  347       GEOSCoordSeq_setXY_r( geosctxt, coord, 3, x + dx2, y + dy2 );
 
  349       GEOSCoordSeq_setX_r( geosctxt, coord, 1, x  + dx1 );
 
  350       GEOSCoordSeq_setY_r( geosctxt, coord, 1, y + dy1 );
 
  351       GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + dx1 + dx2 );
 
  352       GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + dy1 + dy2 );
 
  353       GEOSCoordSeq_setX_r( geosctxt, coord, 3, x + dx2 );
 
  354       GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + dy2 );
 
  359 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  360       GEOSCoordSeq_setXY_r( geosctxt, coord, 1, x + width, y );
 
  361       GEOSCoordSeq_setXY_r( geosctxt, coord, 2, x + width, y + height );
 
  362       GEOSCoordSeq_setXY_r( geosctxt, coord, 3, x, y + height );
 
  364       GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + width );
 
  365       GEOSCoordSeq_setY_r( geosctxt, coord, 1, y );
 
  366       GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + width );
 
  367       GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + height );
 
  368       GEOSCoordSeq_setX_r( geosctxt, coord, 3, x );
 
  369       GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + height );
 
  373 #if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8 
  374     GEOSCoordSeq_setXY_r( geosctxt, coord, 4, x, y );
 
  376     GEOSCoordSeq_setX_r( geosctxt, coord, 4, x );
 
  377     GEOSCoordSeq_setY_r( geosctxt, coord, 4, y );
 
  380     geos::unique_ptr bboxGeos( GEOSGeom_createLinearRing_r( geosctxt, coord ) );
 
  381     bool result = ( GEOSPreparedContainsProperly_r( geosctxt, geom, bboxGeos.get() ) == 1 );
 
  384   catch ( GEOSException &e )
 
  386     qWarning( 
"GEOS exception: %s", e.what() );
 
  396     double x1, 
double y1, 
double x2, 
double y2,
 
  397     double &xRes, 
double &yRes )
 
  402   double A = dx * dx + dy * dy;
 
  403   double B = 2 * ( dx * ( x1 - cx ) + dy * ( y1 - cy ) );
 
  404   double C = ( x1 - cx ) * ( x1 - cx ) + ( y1 - cy ) * ( y1 - cy ) - radius * radius;
 
  406   double det = B * B - 4 * A * C;
 
  407   if ( A <= 0.000000000001 || det < 0 )
 
  414     double t = -B / ( 2 * A );
 
  423     double t = ( -B + std::sqrt( det ) ) / ( 2 * A );
 
static GEOSContextHandle_t getGEOSHandler()
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
static bool computeLineIntersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *x, double *y)
Compute the point where two lines intersect.
static bool isSegIntersects(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
Returns true if the two segments intersect.
static double cross_product(double x1, double y1, double x2, double y2, double x3, double y3)
static int convexHullId(int *id, const std::vector< double > &x, const std::vector< double > &y, int n, int *&cHull)
Compute the convex hull in O(n·log(n))
static int reorderPolygon(int nbPoints, std::vector< double > &x, std::vector< double > &y)
Reorder points to have cross prod ((x,y)[i], (x,y)[i+1), point) > 0 when point is outside.
static double dist_euc2d_sq(double x1, double y1, double x2, double y2)
static bool containsCandidate(const GEOSPreparedGeometry *geom, double x, double y, double width, double height, double alpha)
Returns true if a GEOS prepared geometry totally contains a label candidate.
static void findLineCircleIntersection(double cx, double cy, double radius, double x1, double y1, double x2, double y2, double &xRes, double &yRes)
void heapsort(int *sid, int *id, const std::vector< double > &x, int N)
void heapsort2(int *x, double *heap, int N)
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
#define Q_NOWARN_UNREACHABLE_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define Q_NOWARN_UNREACHABLE_POP