Link to home
Start Free TrialLog in
Avatar of soodsandeep
soodsandeepFlag for India

asked on

drawing graph in C

Hello Experts,

i m trying to write a small program using C Graphics.
i need to draw n connected lines (Actually a Graph), but each line should start where user clicks and should be drawn to the point where user clicked previous time.
in othere words first line is drawn between the point of first and second click, second line is drawn between the point of second and third click and so on.

but my code is not working properly.
please chekck where i am wrong.
Thanks.

my code follows :

#include<graphics.h>
#include<stdio.h>
#include<conio.h>
#include<dos.h>
union REGS in,out;

//mouse routines
int ShowMouse();
void mouseposi(int &xpos,int &ypos,int &click);
int mousehide();
void setposi(int &xpos,int &ypos)

//main starts
int main()
{

     int n, c,x,y,cl,sx,sy, i=0;

     int X[1000], Y[1000] ; //store x,y coordinates of position where user clicks
     int oldx, oldy;
     clrscr();
     int g=DETECT,m;
     initgraph(&g,&m,"c:\tc\bgi");

     //set initial position
     sx=100; sy=200; setposi(sx,sy);

     //Show Mouse
     ShowMouse();
      
     n=5;  //assume i need 5 points

     printf("Please Click at 5 Points ");
     
     i=0;
     while(i<4)
     {
      
         //get mouse position
         mouseposi(x,y,cl);
         if(x!=oldx && y!= oldy)
         {
               gotoxy(1,2);
               printf("       "); //erase old message
               gotoxy(1,2);
               printf("%d,%d",x,y); //display new message
         }

         //save current x,y in oldx,oldy
         oldx=x;
         oldy=y;

         if(cl==1) //if clicked
         {
            putpixel(x-1,y-1,RED); //draw a pixel there.
            X[i]=x-1;
            Y[i]=y-1;
            i++;
            line(X[i],Y[i], X[i-1], Y[i-1]);
         }
     }
getch();
}


//routines to implement mouse follows :

int ShowMouse()
{
      in.x.ax=1;
      int86(51,&in,&out);
      return 1;
}


void mouseposi(int &xpos,int &ypos,int &click)
{
      click=0;
      in.x.ax=3;
      int86(51,&in,&out);
      click=out.x.bx;
      xpos=out.x.cx;
      ypos=out.x.dx;
}


int mousehide()
{
      in.x.ax=2;
      int86(51,&in,&out);
      return 1;
}

void setposi(int &xpos,int &ypos)
{
     in.x.ax=4;
     in.x.cx=xpos;
     in.x.dx=ypos;
     int86(51,&in,&out);
}

Avatar of Infinity08
Infinity08
Flag of Belgium image

Just a few quick observations below. If these don't fix your problem, can you describe what your problem is exactly ?

(a) You forgot a ; at the end of the setposi prototype :

>> void setposi(int &xpos,int &ypos)

(b) You didn't initialize any of the variables. You should do that, or they might contain garbage values that could adversely affect your program's correct execution. For example, oldx and oldy are not initialized, so when you check x and y against them in the first loop iteration, you might get unexpected behavior. Always initialize all of your variables.

(c) Remember that the first point does NOT generate a line yet. You have to wait for the second point before drawing the line.
Avatar of soodsandeep

ASKER

(a) You forgot a ; at the end of the setposi prototype :
>> void setposi(int &xpos,int &ypos)

ok. it was typing mistake. i have corrected it now. it was a simple syntax error.

>>You didn't initialize any of the variables. You should do that, or they might contain garbage values that could adversely affect your program's correct execution. For example, oldx and oldy are not initialized, so when you check x and y against them in the first loop iteration, you might get unexpected behavior. Always initialize all of your variables.

yes. i agree.



(c) Remember that the first point does NOT generate a line yet. You have to wait for the second point before drawing the line.
sorry, i couldnt understand.

actually problem is on my first click only, it comes out of while loop and draws some lines.

Please run it once and only then you can know actual errors.
BTW,
thanks a lot for your reply.


and, please also check my another question at
https://www.experts-exchange.com/questions/24341068/reading-file-using-streams.html
>> (c) Remember that the first point does NOT generate a line yet. You have to wait for the second point before drawing the line.
>> sorry, i couldnt understand.

Ok, the user clicks the first time, so you execute this piece of code :

>>             putpixel(x-1,y-1,RED); //draw a pixel there.
>>             X[i]=x-1;
>>             Y[i]=y-1;
>>             i++;
>>             line(X[i],Y[i], X[i-1], Y[i-1]);

You copy the coordinates into the array, then increment i, which is all fine, but then you draw a line from the point where the user just clicked, to some random point.

You have to wait until the user clicks the second point before drawing the first line.


>> Please run it once and only then you can know actual errors.

I can't run it here, since I don't have access to a platform with the libraries you use atm.

I was just wondering whether you could describe the problem ... so it's easier for me to know where I should look.
>>
You copy the coordinates into the array, then increment i, which is all fine, but then you draw a line from the point where the user just clicked, to some random point.

yes. thats true. it will draw first line randomly.
i will fix this.
but the problem is at my click only, it comes out of loop as if i have clicked n times.

i made another change like :
n=5;  //assume i need 5 points

     printf("Please Click at 5 Points ");
     
     i=0;
     while(i<n)
     {
     
         //get mouse position
         mouseposi(x,y,cl);
         if(x!=oldx && y!= oldy)
         {
               gotoxy(1,2);
               printf("       "); //erase old message
               gotoxy(1,2);
               printf("%d,%d",x,y); //display new message
         }

         //save current x,y in oldx,oldy
         oldx=x;
         oldy=y;

         if(cl==1) //if clicked
         {
            putpixel(x-1,y-1,RED); //draw a pixel there.
            X[i]=x-1;
            Y[i]=y-1;]
            printf("\n\t\t %d",i);     /* CHANGE */****************************
            i++;
            line(X[i],Y[i], X[i-1], Y[i-1]);
         }
     }
getch();
}


and at my first click only it prints
0  
 1  
2  
3
 4

and exits from loop. This is main problem. it does not let me clikc at diffrent positions.

Please Check.

Thanks.
>> but the problem is at my click only, it comes out of loop as if i have clicked n times.

You probably want to reset cl to 0 inside the if block. Otherwise, on the next iteration, cl will still be == 1, even though you already handled that click.
when i click, cl becomes 1, i use it and then i reset to 0, so that it is not reused again untill i click again.

but it is not happening this way.
On My First Click Only, Loop Executes n Times. This is the Actual Problem.    (PLEASE NOTE)
i wish that lines should be drawn at each click(first line may be random, i wil fix this). but even before this, it should get n click from me (from user). but it ends at first click only.

Please Check.
Thanks.
>> when i click, cl becomes 1, i use it and then i reset to 0, so that it is not reused again untill i click again.

Where ? Can you show me your new code ?
yes sure.
here is my new code :
#include<graphics.h>
#include<stdio.h>
#include<conio.h>
#include<dos.h>
union REGS in,out;

//mouse routines

int ShowMouse();
void GetMousePosi(int &xpos,int &ypos,int &click);
int  HideMouse();
void SetMousePosi(int &xpos,int &ypos);

void main()
{

     int n, c,x,y,cl,sx,sy, i=0;

     int X[1000], Y[1000] ; //store x,y coordinates of position where user clicks
     int oldx, oldy;
     clrscr();
     int g=DETECT,m;
     initgraph(&g,&m,"c:\tc\bgi");

     //set initial position
//     sx=100; sy=200; setposi(sx,sy);

     //Show Mouse
     ShowMouse();

     n=5;  //assume i need 5 points

     printf("Please Click at 5 Points ");

     i=0;
     X[i]=0;
     Y[i]=0;
     i=1;
     x=y=0;
     while(1)
     {

         //get mouse position
         GetMousePosi(x,y,cl);
         if(x!=oldx && y!= oldy)
         {
               gotoxy(1,2);
               printf("       "); //erase old message
               gotoxy(1,2);
               printf("%d,%d",x,y); //display new message
         }

         //save current x,y in oldx,oldy
         oldx=x;
         oldy=y;
            /*** Please note ****/
            //if clicked, cl is 1. use it and make it 0
         if(cl==1)
         {
            cl=0;
            putpixel(x-1,y-1,RED); //draw a pixel there.
            X[i]=x-1;
            Y[i]=y-1;
            line(X[i],Y[i], X[i-1], Y[i-1]);
            printf("\n\n\n\t%d", i);
            i++;
            if(i==5)
                  break;
         }
     }
 //    HideMouse();
getch();
}


//routines to implement mouse follows :

int ShowMouse()
{
      in.x.ax=1;
      int86(51,&in,&out);
      return 1;
}


void GetMousePosi(int &xpos,int &ypos,int &click)
{
      click=0;
      in.x.ax=3;
      int86(51,&in,&out);
      click=out.x.bx;
      xpos=out.x.cx;
      ypos=out.x.dx;
}


int HideMouse()
{
      in.x.ax=2;
      int86(51,&in,&out);
      return 1;
}

void SetMousePosi(int &xpos,int &ypos)
{
     in.x.ax=4;
     in.x.cx=xpos;
     in.x.dx=ypos;
     int86(51,&in,&out);
}

A few things, after having a closer look at your code :

(a) You need to initialize the mouse at the start of the program, by doing :

        in.x.ax = 0;
        int86(51, &in, &out);

    (before ShowMouse)

(b) You should also call closegraph at the end


But the real problem is that you're missing a delay at the end of the while loop. Your loop goes too fast, so that it loops several times during the time you press down the button on your mouse (a fraction of a second).

The way to fix that, is to place a delay at the end of the while loop, for example :

        delay(100);
ASKER CERTIFIED SOLUTION
Avatar of jefftope
jefftope
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> You might also want to put a loop

That would be a busy wait - not generally what you want ... A delay or other non-busy wait is often better.
On the other hand, the advantage of the busy wait is that it lasts for exactly as long as the click ... With the delay, you have to arbitrarily pick a click length.