I am using WinBGIm.
#include <iostream>
#include <cmath>
#include "graphics.h"
void Swap(double &a, double &b)
{
double x = a;
a = b;
b = x;
}
double Round(double number)
{
return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5);
}
void PlotPixel(int x, int y, int color)
{
const int radius = 1;
setcolor(color);
circle(400+x,300-y,radius);
}
void DDALine(double x1, double y1, double x2, double y2, int color)
{
//Is it really required?
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
//////////////////////???
double xi = x1;
double yi = y1;
double deltaY = y2 - y1;
double deltaX = x2 - x1;
double m = deltaY / deltaX;
//Is it really required?
/*if(x1 == x2)
{
m = 2;
}*/
if(abs(m)<=1)
{
while (xi<=x2)
{
yi = yi + m;
yi = Round(yi);
PlotPixel(xi, yi, color);
xi = xi + 1;
}
}
if(abs(m)>1)
{
while (yi<=y2)
{
xi = xi + 1/m;
xi = Round(xi);
PlotPixel(xi, yi, color);
yi = yi + 1;
}
}
}
int main()
{
int gm=DETECT, gd=DETECT;
initwindow(1024, 800,"Er");
DDALine(-200, 0, 200, 0, BLUE);
DDALine(0, 200, 0, -200, BLUE);
///////////////////////////////
DDALine(-100, -100, -100, -100, WHITE);
DDALine(-100, -100, -100, 100, WHITE);
DDALine(-100, -100, 100, -100, WHITE);
DDALine(-100, -100, 100, 100, WHITE);
DDALine(-100, 100, -100, -100, WHITE);
DDALine(-100, 100, -100, 100, WHITE);
DDALine(-100, 100, 100, -100, WHITE);
DDALine(-100, 100, 100, 100, WHITE);
/////////////////////////////
DDALine(100, -100, -100, -100, WHITE);
DDALine(100, -100, -100, 100, WHITE);
DDALine(100, -100, 100, -100, WHITE);
DDALine(100, -100, 100, 100, WHITE);
DDALine(100, 100, -100, -100, WHITE);
DDALine(100, 100, -100, 100, WHITE);
DDALine(100, 100, 100, -100, WHITE);
DDALine(100, 100, 100, 100, WHITE);
getch();
closegraph();
}
Output:
1 Answer 1
Only draws straight or 45 degree lines
This code here seems wrong:
while (xi<=x2) { yi = yi + m; yi = Round(yi); PlotPixel(xi, yi, color); xi = xi + 1; }
You are rounding yi
at every step, which means that at every step, either you are going to add 0 or 1 to yi
. That means you can only draw straight or 45 degree lines. What you should do instead is keep yi
unrounded but plot the pixel at the rounded location, like this:
while (xi<=x2)
{
yi = yi + m;
PlotPixel(xi, Round(yi), color);
xi = xi + 1;
}
Of course the other loop needs to be fixed in the same way. I would also suggest inverting m
once instead of once per loop. Additionally, you don't need that other if
statement, it could just be an else
. Full changes:
if(abs(m)<=1)
{
while (xi<=x2)
{
yi = yi + m;
PlotPixel(xi, Round(yi), color);
xi = xi + 1;
}
}
else
{
m = 1/m;
while (yi<=y2)
{
xi = xi + m;
PlotPixel(Round(xi), yi, color);
yi = yi + 1;
}
}
-
\$\begingroup\$ Is swapping required? Is divide by zero testing required? \$\endgroup\$user3804– user38042015年08月20日 17:20:45 +00:00Commented Aug 20, 2015 at 17:20
-
\$\begingroup\$ @anonymous Well, the way your code is written, your loops add 1 to
xi
oryi
, so you need the swaps. If you didn't want to swap you could change your code to add either +1 or -1 on each loop. I would definitely include the divide by zero check. I'm not sure how your code managed to run without it. \$\endgroup\$JS1– JS12015年08月20日 18:11:24 +00:00Commented Aug 20, 2015 at 18:11 -
\$\begingroup\$ me neither..:-) \$\endgroup\$user3804– user38042015年08月20日 18:15:51 +00:00Commented Aug 20, 2015 at 18:15
-
\$\begingroup\$ @anonymous Actually, I think that a double divide by zero results in
inf
instead of throwing an exception. \$\endgroup\$JS1– JS12015年08月20日 18:36:20 +00:00Commented Aug 20, 2015 at 18:36