# a tricky program

Discussion in 'C++' started by sadam, Apr 21, 2011.

1. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Where exactly are you confused? I've goven you some pretty detailed instruction as to how best to proceed but you appear to be ignoring it.

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
ok, well is this program able to give me the solution after some corrections???
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXCIRCLES 20

struct point {
double x;
double y;
};

struct line {
double a; /* Slope */
double b; /* y-intercept */
};

struct circle {
double cx, cy; /* Center coordinates */
double r; /* Circle radius */
};

void ReadFile( const char *filename, point *x, point *y, int *nobst )
{
FILE *file;
int i;
if (( file = fopen( filename, "r" )) == NULL )
{
printf ( "Error opening file!\n" );
exit(1);
}
fscanf( file, "%lf %lf", &point->x, &point->y );
fscanf( file, "%lf %lf", &point->x, &point->y );
fscanf( file, "%d", nobst );
for( i = 0; i <*nobst )
{
fscanf( file, "%lf %lf %1f", &circle.cx,&circle.cy,&circle.r)
}
fclose( file );
}

/* Distance between two points */
double PointToPoint(sturct point *p, struct point *q);

/* Distance between a point and a line */
double PointToLine(struct point *p, struct line *l);

int main()
{
point s;
point t;
int nobst;
circle c[MAXCIRCLES];
ReadFile( "route.dat", &x, &y, &nobst );

line l;
point close;
double d;
double xray = 0.0;
double around = 0.0;
double angle;
double travel;
int i;
double asin(),sqrt();
double distance();

points_to_line(s,t,&l);

for (i=1; i<=nobst; i++) {
closes_point(c[i].c,,l,close);
d = distance(c[i].c,close);
if ((d>=0) &&  (d<c[i].r) && point_in_box(close,s,t){
xray += 2*sqrt(c[i].r*c[i].r) - d*d;
angle = acos(d/c[i].r);
around += ((2*angle)/(2*PI)) * (2*PI*c[i].r);
}
}

dist = distance(s,t) - xray + around;
printf("f\n",dist);
}```
thank you very much, i hope that i will get to a solution soon

3. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Yes, but it will need a number of corrections as well as additional code. The "sturct" typo is still there so it looks like you've done nothing since you last posted it, so check my previous reply for a catalog of syntactic errors - no point me going through the code again.

Have you compiled it yet? What errors does the compiler give you?
If you haven't compiled it yet, why not?

You still haven't done what I suggested, which is to open the file, read the data and display it to the screen. Why not?

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
what do you mean about the struct typo? the struct make me easier to work, why is it wrong?
moreover, the Readfile is working as it should isn't it?

the compiler has many errors mainly because i haven't use some ''names'' before

thank you

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
I am really confused, i have done this so far and it still doesn't work!!
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXCIRCLES 20
#define PI 3,1415

struct point {
double x;
double y;
};

struct line {
double a; /* Slope */
double b; /* y-intercept */
};

struct circle {
double cx, cy; /* Center coordinates */
double r; /* Circle radius */
};

void ReadFile( const char *filename, struct point *x, struct point *y, int *nobst )
{
struct circle *c;
FILE *file;
int i;
if (( file = fopen( filename, "r" )) == NULL )
{
printf ( "Error opening file!\n" );
exit(1);
}
fscanf( file, "%lf %lf", &x->x, &x->y );
fscanf( file, "%lf %lf", &y->x, &y->y );
fscanf( file, "%d", nobst );
for( i = 0; i <*nobst; i++ )
{
fscanf( file, "%lf %lf %1f", &c->cx,&c->cy,&c->r);
}
fclose( file );
}

/* Distance between two points */
double distance(sturct point *p, struct point *q)
{
double dx;
double dy;

dx = q->x - p->x;
dy = q->y - p->y;

return sqrt(dx*dx + dy*dy);
}

/* Distance between a point and a line */
double PointToLine(struct point *p, struct point *q, struct line *l)
{
l->a = (q->y -p->y)/(q->x-p->x);
l->b = p->y - (l->a*p->x);
}

int main()
{
struct point *s;
struct point *t;
int nobst;
struct circle *c;

ReadFile( "route.dat", s, t, &nobst );

struct line *l;
double dist;
double xray = 0.0;
double around = 0.0;
double angle;
double travel;
int i;
double asin(),sqrt();
double distance();

points_to_line(s,t,&l);

for (i=1; i<=nobst; i++)
{
xray += 2*sqrt(c[i].r*c[i].r) - distance(s,t);
angle = acos(distance(s,t)/c[i].r);
around += ((2*angle)/(2*PI)) * (2*PI*c[i].r);

}

dist = distance(s,t) - xray + around;
printf("f\n",dist);
}```
can you help me to make this work?

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
i have a syntax error in my previous post, i wrote 'sturct' instead of 'struct'. but although it doesn't work..please help me, what is going wrong finally??

7. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Sigh. Stop me when you hit a word you don't understand:

What.
Errors.
Does.
The.
Compiler.
Throw?

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
it throws no erros but only one warning '' note: expected 'struct line *' but argument is of type 'struct line **''

however when i run the program it writes me 'error opening file'
that's all, i'm waiting to help me

9. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Really? There are loads of errors. What compiler are you using?

Here's what Visual Studio 2010 makes of the code:

1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(92): error C2660: 'sqrt' : function does not take 1 arguments

It probably bails out early as those are fatal errors anyway. As points_to_line isn't defined, I'll comment that line out. The second error is probably due to this line:
Code:
```double asin(),sqrt();
```
so I'll comment that out as well (and the other local function prototype, which is not necessary), and recompile:

1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(83): warning C4101: 'travel' : unreferenced local variable
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(78): warning C4101: 'l' : unreferenced local variable
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(43): warning C4700: uninitialized local variable 'c' used
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(65): error C4716: 'PointToLine' : must return a value
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(76): warning C4700: uninitialized local variable 't' used
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(76): warning C4700: uninitialized local variable 's' used
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(92): warning C4700: uninitialized local variable 'c' used

"unreferenced local variable" warnings can be ignored for now.
The third is on this line:
Code:
```fscanf( file, "%lf %lf %1f", &c->cx,&c->cy,&c->r);
```
and checking back to the last usage of c
Code:
```struct circle *c;
```
it is indeed uninitialised.

"'PointToLine' : must return a value" is self-explanatory. It doesn't. Since this isn't called anywhere I'll just change the return type to void.

The next two relate to this line:
Code:
```ReadFile( "route.dat", s, t, &nobst );
```
where s and t are undefined:
Code:
```    struct point *s;
struct point *t;
```
so you've declared them as pointers, but you haven't declared two ACTUAL "struct point" variables for them to point at. Based on the problem description I think these should probably not be defined as pointers; these correspond to the driver's start and stop position, correct? So I'll take out the *'s and change the call to ReadFile to take their addresses.

The final warning relates to this line
Code:
```xray += 2*sqrt(c[i].r*c[i].r) - distance(s,t);
```
which is another consequence of leaving c undefined
Code:
```struct circle *c;
```
With the modifications I now get
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(92): error C2664: 'distance' : cannot convert parameter 1 from 'point' to 'point *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(93): error C2664: 'distance' : cannot convert parameter 1 from 'point' to 'point *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>c:\users\dave\documents\visual studio 2010\projects\test1\test1.cpp(98): error C2664: 'distance' : cannot convert parameter 1 from 'point' to 'point *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Still no sign of your compiler's message "expected 'struct line *' but argument is of type 'struct line **''. No usage of line corresponds......except possibly the call to points_to_line(). Does this compiler warning relate to a different version of the code than the latest code you posted?

'error opening file'......hmm. What error, I wonder. If you define as a new global variable:
Code:
```int errno;
```
fopen will write the error code to this file, then you can find out what error with something like:
Code:
```printf ( "Error %d opening file!\n", errno );
```
and by looking up the meaning of errno codes you can find out what the error is. Most likely error is "file not found" - does route.dat exist in the same directory as the program is running? (Note the careful wording. This is NOT necessarily the directory where the executable is located.)

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
what sould i do now? i have been trying for over a week without any result!! can you help me and write me some of the code?

11. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Well I've already told you what code I think you should write next. Several times. So there's no point repeating it.

No I'm not going to write ANY of the code for you. This is YOUR task. You learn programming by programming, not by having others write the code for you. Sorry if that seems harsh, but if I write the code for you this time then that'll create a dependency where every time you're stuck you'll expect me (or some other gullible idiot) to do your homework for you, which is great as far as it goes but on exam day when you have no internet access you will fail the exam.

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
well at least tell me how many functions i need and where do i have the most errors

13. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
How many functions do you need? Well, you could do the whole lot in main, so 1, I suppose.

Where do you have the most errors: difficult to say, they're all over the code. They're mainly caused, IMHO, by you trying to do too much in one go. Keep it simple: write just a few lines of code (5-10) and make sure they compile, run and produce expected results before continuing. Add extra output statements so that you can see what is going on.

But I'm beginning to wonder if this task is simply beyond your level of ability; maybe you should focus on some simpler tasks and come back to this one when you've done a few easier exercises.

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0

i have done this but id doesn't run, can you tell me what's wrong?
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define EPSILON    0.000001        /* a quantity small enough to be zero */
#define    MAXN    100                /* maximum number of circles */
#define DIMENSION    2            /* dimension of points */
#define X        0                /* x-coordinate index */
#define    Y        1                /* y-coordinate index */
#define PI 3,1415
#define max(A, B) ((A) > (B) ? (A) : (B))
#define min(A, B) ((A) < (B) ? (A) : (B))

typedef struct {
double a;                    /* x-coefficient */
double b;                    /* y-coefficient */
double c;                    /* constant term */
} line;

typedef double point[DIMENSION];

typedef struct {
point c;                    /* center of circle */
double r;                    /* radius of circle */
} circle;

point s;                         /* initial position */
point t;                         /* target position */
int ncircles;                     /* number of circles */
circle c[MAXN];                     /* circles data structure */

void ReadFile( const char *filename, point s, point t, int *ncircles )
{
FILE *file;
int i;
if (( file = fopen( filename, "r" )) == NULL )
{
printf ( "Error opening file!\n" );
exit(1);
}

scanf("%lf l%f",&s[X],&s[Y]);
scanf("%lf l%f",&t[X],&t[Y]);
scanf("%d",&ncircles);
for (i=1; i<=*ncircles; i++){
scanf("%lf %lf %lf",&c[i].c[X],&c[i].c[Y],&c[i].r);
}
fclose( file );
}

points_to_line(point p1, point p2, line *l)
{
l->b = 1;
l->a = -(p1[Y]-p2[Y])/(p1[X]-p2[X]);
l->c = -(l->a * p1[X]) - (p1[Y]);
}

point_and_slope_to_line(point p, double m, line *l)
{
l->a = -m;
l->b = 1;
l->c = -((l->a*p[X]) + (l->b*p[Y]));
}

void intersection_point(line l1, line l2, point p)
{
p[X] = (l2.b*l1.c - l1.b*l2.c) / (l2.a*l1.b - l1.a*l2.b);
p[Y] = -(l1.a * p[X] + l1.c) / l1.b;
}

void closest_point(point p_in, line l, point p_c)
{
line perp; // perpendicular to l through (x,y)
if(fabs(l.b) <= EPSILON) // vertical line
{
p_c[X]=-(l.c);
p_c[Y]=p_in[Y];
return;
}

if(fabs(l.a) <= EPSILON) // horizontal line
{
p_c[X]=p_in[X];
p_c[Y]=-(l.c);
return;
}

point_and_slope_to_line(p_in,1/l.a,&perp);
intersection_point(l,perp,p_c);
}

double distance(point p1, point p2)
{
return sqrt(pow(p1[Y]-p2[Y],2) + pow(p1[X]-p2[X],2));
}
int main()
{
line l;
point close;              /* closest point */
double d;                 /* distance from circle-center */
double xray = 0.0;    /* length of intersection with circles */
double around = 0.0;    /* length around circular arcs */
double angle;                /* angle subtended by arc */
double dist;                  /* total travel distance */
int i;
ReadFile( "route.dat", s, t, &ncircles );

points_to_line(s,t,&l);

for (i=1; i<=ncircles; i++) {
closest_point(c[i].c,l,close);
d = distance(c[i].c,close);
if ((d < c[i].r))  {
xray += 2*sqrt(c[i].r*c[i].r - d*d);
angle = acos(d/c[i].r);
around += ((2*angle)/(2*PI)) * (2*PI*c[i].r);
}
}

dist = distance(s,t) - xray + around;
printf("%f\n", dist);
}
```

15. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
"doesn't run" is a bit vague; could you be more specific? If you add some printf statements to the code to let you know where it's up to, does that help you find out where it goes wrong? Presumably the fact that you're expecting it to run means that you got no compiler errors this time.

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
well, i mean that when i try to run it it throws me a blank page!!!
yes no errors!!
i hope that with your compiler there won't be too many errors!!
what do you suggest me to do? how to write printf?

17. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Same way you do at the end of the program. Just put some messages indicating where it's got up to. For example:
Code:
```int main()
{
line l;
point close;              /* closest point */
double d;                 /* distance from circle-center */
double xray = 0.0;    /* length of intersection with circles */
double around = 0.0;    /* length around circular arcs */
double angle;                /* angle subtended by arc */
double dist;                  /* total travel distance */
int i;
printf("Entered main\n");
ReadFile( "route.txt", s, t, &ncircles );
//......and so on
```
You might also find it useful to display numeric values as it goes along, so you can check the results are correct. So again for example:
Code:
```    ReadFile( "route.txt", s, t, &ncircles );
printf("Readfile put values %lf %lf into s[X,Y]\n",s[X],s[Y]);
printf("Readfile put values %lf %lf into t[X,Y]\n",t[X],t[Y]);
```
Of course, all this is a lot easier if you can step through the code in a debugger. What compiler are you using, and what OS?

Joined:
Apr 21, 2011
Messages:
33
0
Trophy Points:
0
i am using the Codeblocks in the Windows7
i just found out that if i put a printf just after the Readfile in the main it doesn't post it. Damn!! what does this mean? all i have done is wrong???!!!

19. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
It means for some reason it's not getting past Readfile. Try adding some printfs to ReadFile and see if you can spot anything.

Joined:
Apr 21, 2011
Messages:
33