What happens when the decimal point error occurs in the other direction? Meaning, what if we got -0.99999999999999934442 instead of -1? Didn't happen in this particular case, but I bet it could.I think a momentary recast of the argument sent to acos would work better. Wouldn't have to change all the variables, just that one. The return from acos will be a double no matter what value you give it. So why not make it a value with acceptable precision?
double theta;double rsquare;double arc;float stepone;rsquare = pow(rad, 2);stepone = (2 * rsquare - pow(chord, 2)) / (2 * rsquare);theta = acos(stepone);
00101015 5 1
powbook:~ lholcombe$ ./a.outEnter a filename for input:file1.datcircle # 1 intersects the line, calculating arc distanceEnter a filename for output:file1.out
15.2837
0510515 6 1
powbook:~ lholcombe$ ./a.outEnter a filename for input:file2.datcircle # 1 does not intersect the line (tangent)Enter a filename for output:file2.out
10
0001010 5 1
powbook:~ lholcombe$ ./a.outEnter a filename for input:file3.datcircle # 1 intersects the line, calculating arc distanceEnter a filename for output:file3.out
11.1416
Aces! Two completely different solutions in two different languages for the same problem with the same answer
So where's the next problem to program?
[declan@localhost curve_challenge]$ ./mainline.p1.x: 0line.p1.y: 0line.p2.x: 10line.p2.y: 10num_circles: 1circle->c.x: 5circle->c.y: 5circle->r: 1The length of the curve is: 14.142136 [proper answer is apparently 15.2837] -- modify input --[declan@localhost curve_challenge]$ ./mainline.p1.x: 0line.p1.y: 5line.p2.x: 10line.p2.y: 5num_circles: 1circle->c.x: 5circle->c.y: 6circle->r: 1The length of the curve is: 10.000000 -- modify input --[declan@localhost curve_challenge]$ ./mainline.p1.x: 0line.p1.y: 0line.p2.x: 0line.p2.y: 10num_circles: 1circle->c.x: 0circle->c.y: 5circle->r: 1The length of the curve is: 10.000000
[declan@localhost curve_challenge]$ ./mainline.p1.x: 5line.p1.y: 0line.p2.x: 5line.p2.y: 10num_circles: 2circle->c.x: 5circle->c.y: 5circle->r: 1circle->c.x: 20circle->c.y: 20circle->r: 2The length of the curve is: 10.000000
Penguin, your code seems to be calculating the lines alone and ignoring all the circles. You could finish it...
/* vectsoln.c Vector solution in C form*/#include #include #include #define TRUE 1#define FALSE 0#define FILENAMELENGTH 40int main(){ /* variable declarations */ /* file read/write variables */ FILE *fRead; FILE *fWrite; char infilename[FILENAMELENGTH]; char outfilename[FILENAMELENGTH]; /* boolean variable type defined */ typedef int bool; /* variables declared from input */ double x1, y1, x2, y2; int i, numcircles; double circx[15], circy[15], radius[15]; /* variables of importance */ double linelength, totalpathlength; int numcirclesintersected=0; /* booleans of interest */ bool EndNotInCircle, LineInRange, LineLongEnough; /* variables for intermediate calculations */ double s1,s2,p1,p2,disttoline,numerator; double halfangle, arclength, chordlength, pathdifference; /* opening the file and reading contents into variables */ /* printf("Enter a filename for input:\n"); scanf("%s", &infilename); */ strncpy(infilename,"data.dat",40); fRead =fopen(infilename, "r"); if (fRead==NULL) { printf("input file unavailable\n"); return 1; } fscanf(fRead, "%lf", &x1); fscanf(fRead, "%lf", &y1); fscanf(fRead, "%lf", &x2); fscanf(fRead, "%lf", &y2); fscanf(fRead, "%d", &numcircles); printf("x1 %f y1 %f x2 %f y2 %f numcircles %i\n",x1,y1,x2,y2,numcircles); if (numcircles>15) { printf("too many circles, aborting\n"); return 1; } else { printf("%i circles in file.\n",numcircles); for(i=0; i { printf("loading circle %i\n",i); fscanf(fRead, "%lf%lf%lf", &circx[i], &circy[i], &radius[i]); printf("circledata x %f y %f r %f \n",circx[i],circy[i],radius[i]); } } fclose(fRead); /* finished loading data (whew) Start interesting stuff */ linelength = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2)); totalpathlength=linelength; for (i=0; i { numerator=fabs( (x2-x1)*(y1-circy[i]) - (x1-circx[i])*(y2-y1) ); disttoline= numerator/linelength; s1=sqrt( pow((circx[i]-x1),2) + pow((circy[i]-y1),2) ); /* s2 is distance from line endpoint 2 to center circle */ s2=sqrt( pow((circx[i]-x2),2) + pow((circy[i]-y2),2) ); /* p1 is the projection of s1 along the line (vector component) */ p1=sqrt( pow(s1,2) - pow(disttoline,2) ); /* p2 is the projection of s2 along the line (vector component) */ p2=sqrt( pow(s2,2) - pow(disttoline,2) ); if ( ( s1 < radius[i] ) || ( s2 < radius[i] ) ) { EndNotInCircle=FALSE; } else { EndNotInCircle=TRUE; } if ( disttoline < radius[i] ) { LineInRange = TRUE; } else { LineInRange = FALSE; } if ( ( p1 < linelength ) && ( p2 < linelength ) ) { LineLongEnough=TRUE; } else { LineLongEnough=FALSE; } /* key conditional for intersecting a circle */ if (EndNotInCircle==TRUE && LineInRange==TRUE && LineLongEnough==TRUE) { numcirclesintersected++; halfangle=acos(disttoline/radius[i]); chordlength=2*radius[i]*sin(halfangle); arclength=2*halfangle*radius[i]; pathdifference=arclength-chordlength; } else { pathdifference=0; } totalpathlength=totalpathlength+pathdifference; } printf("Total number of circles intersected: %d\n",numcirclesintersected); printf("Original path Length %f\n",linelength); printf("Final path Length %f\n",totalpathlength); /* writing the output to a file */ /**printf("Enter a filename for output:\n"); scanf("%s", &outfilename);*/ strncpy(outfilename,"out.dat",40); fWrite = fopen(outfilename, "w"); if (fWrite==NULL) { printf("output file unavailable\n"); return 1; } fprintf(fWrite, "%f\n", totalpathlength); fclose(fWrite); return 0; }
00101025 5 120 20 2
Total number of circles intersected: 1Original path Length 14.142136Final path Length 15.283728