Search code examples
ccastingqsort

How to sort points based on the slope they make with other reference point using qsort() ? (Without qsort_r()/qsort_s())


I need to find more than 3 collinear points (by checking slopes between them).

Here is the code that gives slopes:

#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <search.h>
#define inf INFINITY
typedef struct point_ {
    int x;
    int y;
}point;
float slope(point *p1,point *p2) {
    if(p2->y==p1->y && p2->x!=p1->x) return 0;//horizontal line segment
   else if(p2->x==p1->x && p2->y!=p1->y) return inf; //vertical line segment
   else if(p2->x==p1->x && p2->y==p1->y) return -inf;//point to itself
   else 
   return (p2->y-p1->y)/((float)(p2->x-p1->x));
}

I need to sort the points based upon the slope they make with a reference point so that I can find collinearities by checking no.of slopes that are equal.

As qsort_s()/qsort_r() cannot be implemented in all I have tried using sort_r from this SO discussion.

int fastCollinearPoints(point *p,int n) {
    point copy[n];
    int i;
    for(i=0;i<n;i++) copy[i]=p[0];
    sort_r(copy,n,sizeof(point),slopeOrder,&copy[0]);
}

compare function

int slopeOrder(const void *p11,const void *p22,void *arg) {
    point *p1 = (point *) p11;
    point *p2 = (point *) p22;
    point *p= (point*) p;
    int a=slope(p,p1),b=slope(p,p2);
    if(a<b) return -1;
    else if(a>b) return 1;
    else return 0;
}

Facing an error undefined reference to qsort_r by implementing this way. If this can be implemented using qsort_r()/qsort_s(), what changes do I require for compare function?


Solution

  • The 'slopeOrder' does not use the context parameter (arg) at all, Instead it 'manufactor' a point *p = (...) p

    Try:

    int slopeOrder(const void *p11,const void *p22,void *arg) {
        point *p1 = (point *) p11;
        point *p2 = (point *) p22;
    ///    point *p= (point*) p;
    /// REPLACEMENT:
        point *p = (point *p) arg ;
    

    It's hard to verify without specific example to replicate problem.

    Also, two more warning from strict compile (c99 -Wall):

    • fastCollinearPoints does not return any value
    • The following is no-op: if(prevSlope!=currSlope) numOfSeg; //for other sets of collinears