graphics in c

R

Raj

following is a code for scan converting a line using DDA algorithm.
But I'm not getting any line in the output. The code is:
/*start*/
#include <graphics.h>
#include <stdio.h>
float m;
main()
{
int x1,y1,x2,y2;
float dx,dy;
void slopelessthanone(int,int,int);
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
printf("Enter coordinates of first point:");
scanf("%d%d",&x1,&y1);
printf("Enter coordinates of second point:");
scanf("%d%d",&x2,&y2);
dx=x2-x1;
dy=y2-y1;
m=dy/dx;
printf("%f",m);
if (abs(m)<1) /*I'm considering only one case initially*/
slopelessthanone(x1,x2,y1);
getch();
closegraph();
return;
}
void slopelessthanone(int x1, int y1, int x2)
{
float x,y;
int i=1;
x=x1;
y=y1;
clrscr();
while(x<=x2){
putpixel(x,y,WHITE);
x+=1;
y+=i*m;
i++;
}
}
/*end

Basically in the output when i enter coordinates of the two points,
only one dot(i.e. one pixel) gets plotted. There is no line segment. I
guess this means that the while loop is executing only once. But i
couldn't find the reason.
If anybody could help... thanx!
 
R

Rouben Rostamian

float m; [...]
void slopelessthanone(int x1, int y1, int x2)
{
float x,y;
int i=1;
x=x1;
y=y1;
clrscr();
while(x<=x2){
putpixel(x,y,WHITE);
x+=1;
y+=i*m;
i++;
}
}

The intention here is to draw points on a line segment
with slope m that starts at (x1,y1) and extends to x = x2.

In each iteration x is incremented by 1. The corresponding y
should be incremented by m. Therefore you should say y+=m,
not y+=i*m.
 
A

Army1987

following is a code for scan converting a line using DDA algorithm.
But I'm not getting any line in the output. The code is:
/*start*/
#include <graphics.h>
This isn't standard C, so it is off-topic here. But there is at
least one problem which is not about system-specific extensions.
#include <stdio.h>
float m;
Better declare it as local to main() and pass it to the function.
main()
{
int x1,y1,x2,y2;
float dx,dy;
void slopelessthanone(int,int,int);
It is not very useful to declare functions at block scope, unless
it is a one-purpose function which is only called by another
function which acts as an interface. I'd put that prototype before
main().
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
printf("Enter coordinates of first point:");
Unless you don't call fflush(stdout), the output isn't guaranteed
to show up until a newline is printed.
scanf("%d%d",&x1,&y1);
You should check whether the scanf() succeeded. Read www.c-faq.com
section 12.
printf("Enter coordinates of second point:");
scanf("%d%d",&x2,&y2);
dx=x2-x1;
dy=y2-y1;
m=dy/dx;
printf("%f",m);
if (abs(m)<1) /*I'm considering only one case initially*/
slopelessthanone(x1,x2,y1);
getch();
In standard C it is getchar();
(Although it won't work because it will read the newline which
scanf() left unread on the input stream.)
closegraph();
return;
main() returns an int. Return 0 or EXIT_SUCCESS to indicate
success, or EXIT_FAILURE to indicate failure (these are defined in
}
void slopelessthanone(int x1, int y1, int x2)
{
float x,y;
int i=1;
x=x1;
y=y1;
clrscr();
while(x<=x2){
putpixel(x,y,WHITE);
x+=1;
y+=i*m;
This increments y more than it should.
For example, suppose x1 is 10, y1 is 10, x2 is 400, m is 0.7.
The first repetition of the loop calls putpixel(10, 10, WHITE),
increments x to 11, y to 10.7 and i to 2. The second repetition
calls putpixel(11, 10.7, WHITE) and increases x to 12 (so far,
fine), it increases y by i * m which is now 1.4, that is y becomes
12.1, and i becomes 3. This should display a parabola, in theory.
You don't need any i here. Just:
void slopelessthanone(int x1, int x2, int y1, double m)
{
double x, y; /* no need to save space with float */
clrscr();
y = y1;
for (x = x1; x <= x2; x++) {
putpixel(x, y, WHITE);
y += m;
}
}
If it still doesn't work, there is something wrong with putpixel()
which is off topic here. Ask in a group about your system.
 
R

Raj

This isn't standard C, so it is off-topic here. But there is at


Better declare it as local to main() and pass it to the function.> main()

It is not very useful to declare functions at block scope, unless
it is a one-purpose function which is only called by another
function which acts as an interface. I'd put that prototype before
main().> initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

Unless you don't call fflush(stdout), the output isn't guaranteed
to show up until a newline is printed.> scanf("%d%d",&x1,&y1);

You should check whether the scanf() succeeded. Readwww.c-faq.com
section 12.> printf("Enter coordinates of second point:");

In standard C it is getchar();
(Although it won't work because it will read the newline which
scanf() left unread on the input stream.)> closegraph();

main() returns an int. Return 0 or EXIT_SUCCESS to indicate
success, or EXIT_FAILURE to indicate failure (these are defined in


This increments y more than it should.> i++;

For example, suppose x1 is 10, y1 is 10, x2 is 400, m is 0.7.
The first repetition of the loop calls putpixel(10, 10, WHITE),
increments x to 11, y to 10.7 and i to 2. The second repetition
calls putpixel(11, 10.7, WHITE) and increases x to 12 (so far,
fine), it increases y by i * m which is now 1.4, that is y becomes
12.1, and i becomes 3. This should display a parabola, in theory.
You don't need any i here. Just:
void slopelessthanone(int x1, int x2, int y1, double m)
{
double x, y; /* no need to save space with float */
clrscr();
y = y1;
for (x = x1; x <= x2; x++) {
putpixel(x, y, WHITE);
y += m;
}}

If it still doesn't work, there is something wrong with putpixel()
which is off topic here. Ask in a group about your system.

1.I found it the most relevant group for my query. There's one group
for graphics algos but it has low activity and doesn't specifically
concern C.

2.I agree i could have declared m inside main but i guess declaring it
the way i did doesn't change the output.

3.Same goes for the function.

4.There could have been a problem here with scanf if i'd have used
gets anywhere after scanf. Flushing the input/output stream doesn't
make any sense here unless we're a bit pedantic ;)

5.Again, returning 0 or just returning doesnot affect the output in
any way.

6.Well, i do agree with your last point. My logic is a bit flawed
here. Basically i was assuming m<0.5. But even if we increment y by m
it doesnot give accurate result. Basically what i want is that y
remains same if its decimal part is< 0.5 but gets incremented by 1
otherwise. But since in c, even 10.7 will be rounded off to 10 in
putpixel, i had used i variable.
Guess i'll have to sacrifice accuracy here a bit...
 
B

Ben Bacarisse

6.Well, i do agree with your last point. My logic is a bit flawed
here. Basically i was assuming m<0.5. But even if we increment y by m
it doesnot give accurate result. Basically what i want is that y
remains same if its decimal part is< 0.5 but gets incremented by 1
otherwise. But since in c, even 10.7 will be rounded off to 10 in
putpixel, i had used i variable.
Guess i'll have to sacrifice accuracy here a bit...

If you don't like Army1987' solution of making y a double, you can write

y = y1 + (int)(i * m);

You can control the rounding any way you like (by adding 0.5, say, to
i * m) or by starting i at 0 rather than 1...

<off topic>Search for Bresenham's 1965 line-drawing algorithm if you want
an integer-only solution.</off topic>

Your other problem (and this might explain your reported problem of
the loop executing only once) is that you pass y1 as the third
parameter to slopelessthanone rather than x2.
 
R

Raj

If you don't like Army1987' solution of making y a double, you can write

y = y1 + (int)(i * m);

You can control the rounding any way you like (by adding 0.5, say, to
i * m) or by starting i at 0 rather than 1...

<off topic>Search for Bresenham's 1965 line-drawing algorithm if you want
an integer-only solution.</off topic>

Your other problem (and this might explain your reported problem of
the loop executing only once) is that you pass y1 as the third
parameter to slopelessthanone rather than x2.

Well yes... i also figured out the 0.5 addition from someone else. And
i guess it would be fine enough if i add anly y+m and not use i at
all. And i AM using x2 as my 3rd parameter. Check my earlier post :)
Well my new while loop is:

while(x<=x2){
x+=1;
y+=m;
putpixel(x,y+0.5,WHITE);
}

But it's still not working! :(
& i still dont understand why i should use y as double.
 
B

Ben Bacarisse

Raj said:
Well yes... i also figured out the 0.5 addition from someone else. And
i guess it would be fine enough if i add anly y+m and not use i at
all. And i AM using x2 as my 3rd parameter. Check my earlier post :)
Well my new while loop is:

while(x<=x2){
x+=1;
y+=m;
putpixel(x,y+0.5,WHITE);
}

But it's still not working! :(
& i still dont understand why i should use y as double.

This will get confusing if you post fragments. Is y double in the
above? It looks OK (as far as one can tell from a fragment of code)
if y is a double, and it looks like it won't work at all if y is
declared int. If you are puzzled by why it works when y is a double
but not when y is an int, then you examine the output of this program
for clues:

#include <stdio.h>

int main(void)
{
int i, iy = 1;
double dy = 1, m = 0.4;
for (i = 0; i < 10; i++) {
iy += m;
dy += m;
printf("%d: iy = %d, dy = %.1f, dy converted to int = %d\n",
i, iy, dy, (int)dy);
}
return 0;
}

Any good C book should be able to explain what happens when you add a
floating point quantity to an integer variable.
 
R

Raj

This will get confusing if you post fragments. Is y double in the
above? It looks OK (as far as one can tell from a fragment of code)
if y is a double, and it looks like it won't work at all if y is
declared int. If you are puzzled by why it works when y is a double
but not when y is an int, then you examine the output of this program
for clues:

#include <stdio.h>

int main(void)
{
int i, iy = 1;
double dy = 1, m = 0.4;
for (i = 0; i < 10; i++) {
iy += m;
dy += m;
printf("%d: iy = %d, dy = %.1f, dy converted to int = %d\n",
i, iy, dy, (int)dy);
}
return 0;

}

Any good C book should be able to explain what happens when you add a
floating point quantity to an integer variable.

I just meant that i've taken y as a float & not double... still no
output...
 
A

Army1987

On Sun, 12 Aug 2007 08:00:01 -0700, Raj wrote:
[I changed the layout to be more readable. Now the comments are
under the text they refer to.]
1.I found it the most relevant group for my query. There's one group
for graphics algos but it has low activity and doesn't specifically
concern C.

Ok, I only meant that, if it turned out that it is the function
putpixel() which is broken, you should go to a group about the
system which provided it (e.g. your OS, your graphic library, or
whatever).
2.I agree i could have declared m inside main but i guess declaring it
the way i did doesn't change the output.

No, it wouldn't. It was just a suggestion on coding style.
3.Same goes for the function.

Same thing as above.
4.There could have been a problem here with scanf if i'd have used
gets anywhere after scanf. Flushing the input/output stream doesn't
make any sense here unless we're a bit pedantic ;)

There could be a problem with scanf even if the user wrote
something other than a number. Note that %d is for integers, so
even the point in 10.0 qualifies as "other than a number". And
while on your system the output is shown immediately, on other
systems it is only shown as soon as a newline is printed. (Yes, on
5.Again, returning 0 or just returning doesnot affect the output in
any way.

Very poor reason to save two keystrokes. I think that returning
nothing is Undefined Behavior, so, as far as the Standard is
concerned, it *could* affect the output (though I admit that very
likely it won't).
6.Well, i do agree with your last point. My logic is a bit flawed
here. Basically i was assuming m<0.5. But even if we increment y by m
it doesnot give accurate result. Basically what i want is that y
remains same if its decimal part is< 0.5 but gets incremented by 1
otherwise. But since in c, even 10.7 will be rounded off to 10 in
putpixel, i had used i variable.

That won't help.
Try the function above, but with
putpixel(x, (int)(y + 0.5), WHITE);
HTH.
Guess i'll have to sacrifice accuracy here a bit...
Anyway, that's no point in being more accurate than to one pixel
(unless putpixel() takes floating-point numbers and performs
anti-aliasing when they're not integers...)
 
A

Army1987

This will get confusing if you post fragments. Is y double in the
above? It looks OK (as far as one can tell from a fragment of code)
if y is a double, and it looks like it won't work at all if y is
declared int.
[snip]

I just meant that i've taken y as a float & not double... still no
output...
This can't be the cause of your problem.
Try replacing putpixel(x, y+0.5, WHITE) with
printf("%d %d\n", (int)x, (int)(y + 0.5)); and examine the output.

Anyway, usually there is no point in using float instead of
double, as floats will be automatically converted to doubles in
operations, so they are likely to be slower. Use float only when
saving space is vital (e.g. you have an array with one thousand
of them).
 
R

Raj

Ok here's my new (& i guess improved! :)) code.... but i guess there's
some problem in the sense that all kinds of lines aren't getting
plotted properly (at least that's what i think)... check it out plz...

/*start*/
#include <graphics.h>
#include <stdio.h>
void drawaxes();
void slopelessthanone(double,double,double,double);
void slopegreaterthanone(double,double,double,double);
main()
{
int gdriver = DETECT, gmode, errorcode;
int originx,originy;
double x1,y1,x2,y2,dx,dy,m;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
errorcode = graphresult();
if (errorcode != grOk)
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1);
}
originx=getmaxx()/2;
originy=getmaxy()/2;
printf("Enter coordinates of first point:");
scanf("%lf%lf",&x1,&y1);
printf("Enter coordinates of second point:");
scanf("%lf%lf",&x2,&y2);
if (x1>=0) /*rounding off*/
x1+=0.5;
else
x1-=0.5;
if (y1>=0)
y1+=0.5;
else
y1-=0.5;
if (x2>=0)
x2+=0.5;
else
x2-=0.5;
if (y2>=0)
y2+=0.5;
else
y2-=0.5;
dx=x2-x1;
dy=y2-y1;
m=dy/dx;
x1+=originx; /*shifting the coordinate system*/
y1+=originy;
x2+=originx;
y2+=originy;
if (abs(m)<1)
slopelessthanone(x1,y1,x2,m);
if (abs(m)>=1)
slopegreaterthanone(y1,y2,x1,m);
getch();
closegraph();
return;
}
void drawaxes() /*drawing coordinate axes*/
{
line(getmaxx()/2, 0, getmaxx()/2, getmaxy());
line(0, getmaxy()/2, getmaxx(), getmaxy()/2);
}
void slopelessthanone(double x1, double y1, double x2, double m)
{
double x,y;
x=x1;
y=y1;
clrscr();
drawaxes();
if (x1<x2)
while(x<=x2){
if (y>=0)
putpixel(x,y+0.5,WHITE);
else
putpixel(x,y-0.5,WHITE);
x+=1;
y+=m;
}
else
while(x>=x2){
if (y>=0)
putpixel(x,y+0.5,WHITE);
else
putpixel(x,y-0.5,WHITE);
x-=1;
y-=m;
}
}
void slopegreaterthanone(double y1, double y2, double x1, double m)
{
double x,y;
y=y1;
x=x1;
clrscr();
drawaxes();
if (y1<y2)
while(y<=y2){
if (x>=0)
putpixel(x+0.5,y,WHITE);
else
putpixel(x-0.5,y,WHITE);
y+=1;
x+=m;
}
else
while(y>=y2){
if (x>=0)
putpixel(x+0.5,y,WHITE);
else
putpixel(x-0.5,y,WHITE);
y-=1;
x-=m;
}
}

I've devoted a lot of time to this... & honestly i don't know even if
there is a mistake here... but certain lines are going way off from
what they should look like...
 
V

Very.Little.Gravitas.Indeed

printf("Enter coordinates of first point:");
scanf("%lf%lf",&x1,&y1);
printf("Enter coordinates of second point:");
scanf("%lf%lf",&x2,&y2);

What inputs is your program receiving?

I recall issues with scanf picking up newlines and other characters
that you may not want from the buffer, as they say garbage in garbage
out :)
 
R

Raj

What inputs is your program receiving?

I recall issues with scanf picking up newlines and other characters
that you may not want from the buffer, as they say garbage in garbage
out :)

Inputs are the coordinates... can be integers or real values....
fflush(stdin) doesn't help in any way... i've tried it...
 
V

Very.Little.Gravitas.Indeed

Inputs are the coordinates... can be integers or real values....
fflush(stdin) doesn't help in any way... i've tried it...

If the data input you are recieving in the program is correct then the
logic must be faulty

Produce a set of data and identify the data that gives the wrong
output.

Then identify the calculations your program goes through with that
data to identify the problem.
 
C

Chris Dollin

Raj said:
Inputs are the coordinates... can be integers or real values....
fflush(stdin) doesn't help in any way... i've tried it...

Of course not -- the action of `fflush` on an /input/ stream is
undefined.

At the very very least, if you're going to wrap the piano wire of
`scanf` round your wrists, have available the needles, thread, and
bandages of echoing your input when you've read it. It's very
enlightening when your input looks like two perfectly reasonable
floating-point numbers and the output looks like the diameter of
the Earth in angstroms. Or perhaps parsecs.

Also, check the return value of `scanf`.

Things are significantly more manageable if you read the entire input
line first (with `fgets` or Some Similar Utility Function) and
then read your numbers out of /that/ using `sscanf`. At least if
this gose worng you're not left with the input stream in An
Interesting Condition.
 
U

user923005

following is a code for scan converting a line using DDA algorithm.
But I'm not getting any line in the output. The code is:
/*start*/
#include <graphics.h>
#include <stdio.h>
float m;
main()
{
int x1,y1,x2,y2;
float dx,dy;
void slopelessthanone(int,int,int);
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
printf("Enter coordinates of first point:");
scanf("%d%d",&x1,&y1);
printf("Enter coordinates of second point:");
scanf("%d%d",&x2,&y2);
dx=x2-x1;
dy=y2-y1;
m=dy/dx;
printf("%f",m);
if (abs(m)<1) /*I'm considering only one case initially*/
slopelessthanone(x1,x2,y1);
getch();
closegraph();
return;}

void slopelessthanone(int x1, int y1, int x2)
{
float x,y;
int i=1;
x=x1;
y=y1;
clrscr();
while(x<=x2){
putpixel(x,y,WHITE);
x+=1;
y+=i*m;
i++;
}}

/*end

Basically in the output when i enter coordinates of the two points,
only one dot(i.e. one pixel) gets plotted. There is no line segment. I
guess this means that the while loop is executing only once. But i
couldn't find the reason.
If anybody could help... thanx!

This is from Graphics Gems:
void digline(int x1, int y1, int x2, int y2, void (*dotproc)
(int,int))
{
int d,
x,
y,
ax,
ay,
sx,
sy,
dx,
dy;

dx = x2 - x1;
ax = (((dx)<0) ? -(dx) : (dx)) << 1;
sx = (((dx)<0) ? -1 : 1);
dy = y2 - y1;
ay = (((dy)<0) ? -(dy) : (dy)) << 1;
sy = (((dy)<0) ? -1 : 1);

x = x1;
y = y1;
if (ax > ay) {
d = ay - (ax >> 1);
for (;;) {
(*dotproc) (x, y);
if (x == x2)
return;
if (d >= 0) {
y += sy;
d -= ax;
}
x += sx;
d += ay;
}
} else {
d = ax - (ay >> 1);
for (;;) {
(*dotproc) (x, y);
if (y == y2)
return;
if (d >= 0) {
x += sx;
d -= ay;
}
y += sy;
d += ax;
}
}
}
 
U

user923005

P.S.
Posts about how to do graphics (in any language) are better targeted
to news:comp.graphics.algorithms
 
C

CBFalconer

Raj said:
following is a code for scan converting a line using DDA algorithm.
But I'm not getting any line in the output. The code is:
/*start*/
#include <graphics.h>
#include <stdio.h>
float m;
main() {
int x1,y1,x2,y2;
float dx,dy;
void slopelessthanone(int,int,int);

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
printf("Enter coordinates of first point:");
scanf("%d%d",&x1,&y1);
printf("Enter coordinates of second point:");
scanf("%d%d",&x2,&y2);
dx=x2-x1;
dy=y2-y1;
m=dy/dx;
printf("%f",m);
if (abs(m)<1) /*I'm considering only one case initially*/
slopelessthanone(x1,x2,y1);
getch();
closegraph();
return;
}
void slopelessthanone(int x1, int y1, int x2) {
float x,y;
int i=1;

x=x1;
y=y1;
clrscr();
while(x<=x2){
putpixel(x,y,WHITE);
x+=1;
y+=i*m;
i++;
}
}
/*end

Basically in the output when i enter coordinates of the two points,
only one dot(i.e. one pixel) gets plotted. There is no line segment. I
guess this means that the while loop is executing only once. But i
couldn't find the reason.
If anybody could help... thanx!

Your question is unanswerable here, since you are using
non-standard things. From our viewpoint:

Undefined: graphics.h, initgraph, getch, closegraph, clrscr,
putpixel.

main is an int function. Return one.

slopelessthanone should precede main, so defined when called.

c.l.c discusses the standard C language, not system specific
variations.

In general, when posting code, try to use adequate blanks. There
are no prizes for suppressing blanks in source code.
 
A

Army1987

Ok here's my new (& i guess improved! :)) code.... but i guess there's
some problem in the sense that all kinds of lines aren't getting
plotted properly (at least that's what i think)... check it out plz...
[snip]
void slopegreaterthanone(double y1, double y2, double x1, double m)
{
double x,y;
y=y1;
x=x1;
clrscr();
drawaxes();
if (y1<y2)
while(y<=y2){
if (x>=0)
putpixel(x+0.5,y,WHITE);
else
putpixel(x-0.5,y,WHITE);
y+=1;
x+=m;
}
else
while(y>=y2){
if (x>=0)
putpixel(x+0.5,y,WHITE);
else
putpixel(x-0.5,y,WHITE);
y-=1;
x-=m;
}
}

I've devoted a lot of time to this... & honestly i don't know even if
there is a mistake here... but certain lines are going way off from
what they should look like...
As I suggested before, try replacing putpixel() calls with
printf() calls, this should make it easier to figure out what's
wrong.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top