001: #include<stdio.h>
002: #include<stdlib.h>
003: #include<math.h>
004: #include<time.h>
005: 
006: #define MDIST    3.0
007: #define MAXTRIES 1000
008: 
009: struct point
010: {
011:   double x,y;
012: };
013: 
014: double dist(double a, double b, double c, double x, double y);
015: 
016: 
017: int main(int argc, char **argv){
018: 
019:   srand(time(NULL)); // later we have to use rand(), therefore we have to initialize the random generator using srand()
020: 
021:   char filename[1000];
022:   printf("Enter the file name: ");
023:   scanf("%s", filename);
024:   FILE *myfile = fopen(filename, "r");
025:   if(!myfile)
026:   {
027:     perror("");
028:     exit(EXIT_FAILURE);
029:   }
030: 
031:   // read how many rows we have in file to understand how many pooint we need to read
032:   char tmp[1000];
033:   int npoints = 0;
034:   while(fscanf(myfile, " %[^\n]", tmp) == 1)
035:     ++npoints;
036: 
037:   // printf("DEBUG: we have %d points\n", npoints);
038: 
039:   // use VLA for simplicity
040: 
041:   struct point points[npoints];
042: 
043:   // re-read the file and fill in the array
044:   rewind(myfile);
045:   for(int i = 0; i < npoints; ++i)
046:     fscanf(myfile,"%lf %lf", &points[i].x, &points[i].y);
047:   fclose(myfile);
048: 
049:   // DEBUG: check if all data have been read
050:   /*
051:   for(int i = 0; i < npoints; ++i)
052:     printf("#%d:\t%g\t%g\n", i, points[i].x, points[i].y);
053:    */
054: 
055: 
056:   double a, b, c;  // stright line parameters
057:   float perc    = 0;  // how many points are close to the straight line
058:   float maxperc = 0;  // max obtained percentage
059:   double ma, mb, mc;  // a, b & c that correspond to max percentage
060:   int ntest     = 0;  // count how many guesses we test
061:   do
062:   {
063:     ++ntest;
064: 
065:     // select 2 random elements
066:     int p1, p2;
067:     p1 = rand()%npoints;
068:     do
069:     {
070:       p2 = rand()%npoints;
071:     }
072:     while(p1 == p2); // they must be distinct points
073: 
074:     a = (points[p1].y - points[p2].y)/(points[p1].x * points[p2].y - points[p2].x * points[p1].y);
075:     b = (points[p2].x - points[p1].x)/(points[p1].x * points[p2].y - points[p2].x * points[p1].y);
076:     c = 1;
077: 
078: 
079:     int closepoints = 0; // let's count points that are close to ax+by+c=0 line
080:     for(int i = 0; i < npoints; ++i)
081:       if(dist(a, b, c, points[i].x, points[i].y) < MDIST)
082:   ++closepoints;
083: 
084:     perc = closepoints/(float)npoints; // we need an explicit cast, otherwise -> integer divide
085: 
086:     //printf("DEBUG: a = %g   b = %g   c = %g  (%g%%)\n", a, b, c, perc);
087: 
088:     // update max percentage
089:     if(perc > maxperc)
090:     {
091:       maxperc = perc;
092:       ma      = a;
093:       mb      = b;
094:       mc      = c;
095:     }
096:   }
097:   while(perc < 0.8 && ntest < MAXTRIES);
098: 
099:   printf("Max percentage (%g%%), obtained with a = %g   b = %g   c = %g  in %d iterations\n", maxperc, a, b, c, ntest);
100: 
101:   // create output file
102:   myfile = fopen("output.dat", "wb");
103:   if(!myfile)
104:   {
105:     perror("");
106:     exit(EXIT_FAILURE);
107:   }
108: 
109:   // write points in binary file
110:   for(int i = 0; i < npoints; ++i)
111:     if(dist(a, b, c, points[i].x, points[i].y) < MDIST)
112:     {
113:       fwrite(&points[i].x, sizeof(points[i].x), 1, myfile);
114:       fwrite(&points[i].y, sizeof(points[i].y), 1, myfile);
115:     }
116:     else
117:     {
118:       //printf("DEBUG: skip point %g %g\n", points[i].x, points[i].y);
119:     }
120:   fclose(myfile);
121: 
122: 
123:   return 0;
124: }
125: 
126: double dist(double a, double b, double c, double x, double y)
127: {
128:   return  fabs(a*x+b*y+c)/sqrt(a*a+b*b);
129: }
130: