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: