画线算法的实现不能正常工作
Implementation of Line Drawing Algorithm doesn't work properly
第一个问题,我试着计算了四个象限的表达式,di+1=di+2*Δy−2*Δx(yi+1−yi)
。不考虑象限,发现表达是一样的,包括符号。
我是对的,还是我计算有误(所以我错了)?
第二个问题,如果这个表达式只适用于第一个八位位组,我如何将它应用到其他八位位组?对我来说,无法确定我正在处理哪个八位字节。因为,m 的值总是代表两个相反的八位字节。例如,如果 0<m<1
,则表示第 1 个和第 5 个八位字节。对吗?
第三,如何确定di的initial/starting值?
#include <iostream>
#include "utils.h"
void BresenhamLine(double x1, double y1, double x2, double y2, int color)
{
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
double x = x1;
double y = y1;
double dx = x2 - x1;
double dy = y2 - y1;
double dt = 2 * (dy - dx);
double ds = 2 * dy;
double d = 2*dy - dx;
PlotPixel(x, y, color);
if(dx>=dy)
{
while(x<=x2)
{
x++;
if(d<0)
{
d = d + ds;
}
else
{
y++;
d = d + dt;
}
PlotPixel(x, y, color);
}
}
else
{
while(y<=y2)
{
y++;
if(d<0)
{
x++;
d = d + dt;
}
else
{
d = d + ds;
}
PlotPixel(x, y, color);
}
}
}
int main()
{
int gm = DETECT;
int gd = DETECT;
initgraph(&gm, &gd, "");
double x1 = 0;
double y1 = 0;
double r = 50;
double x2 = 0;
double y2 = 0;
double signx = 0;
double signy = 0;
for(int theta=0 ; theta<=360 ; theta++)
{
x2 = r * cos(DegreeToRad((double) theta));
y2 = r * sin(DegreeToRad((double) theta));
x1 = 5 * cos(DegreeToRad((double) theta));
y1 = 5 * sin(DegreeToRad((double) theta));
BresenhamLine(x1, y1, x2, y2, YELLOW);
}
getch();
closegraph();
return 0;
}
穿过第 2 和第 4 象限的线未显示。
如何通过对我的代码进行一些小改动来解决这个问题?
有了这个输入:x1: 100 y1: -100 x2: -100 y2: 100
这个逻辑:
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
失败。
此页面是一个很好的起点。它还显示了 1 个八分圆的代码:
http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
我认为你需要交换 x
if x1 > x2
和交换 y
if y1 > y2
但不交换 both 如果其中只有一个为真。
Wikipedia page 的 外部链接 部分包含几个指向您可以研究的现成实现的链接。
试试这个:
void BresenhamLine( double x1, double y1, double x2, double y2, int color )
{
const bool steep = (std::abs(y2 - y1) > std::abs(x2 - x1));
if(steep)
{
std::swap(x1, y1);
std::swap(x2, y2);
}
if(x1 > x2)
{
std::swap(x1, x2);
std::swap(y1, y2);
}
double dx = x2 - x1;
double dy = std::abs(y2 - y1);
double error = dx / 2;
int ystep = (y1 < y2) ? 1 : -1;
int y = (int)y1;
int maxX = (int)x2;
for(int x=(int)x1; x<maxX; x++)
{
if(steep)
{
PlotPixel(y, x, color);
}
else
{
PlotPixel(x, y, color);
}
error -= dy;
if(error < 0)
{
y += ystep;
error += dx;
}
}
}
我通过稍微修改这里的代码得到这个:http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#C.2B.2B
第一个问题,我试着计算了四个象限的表达式,di+1=di+2*Δy−2*Δx(yi+1−yi)
。不考虑象限,发现表达是一样的,包括符号。
我是对的,还是我计算有误(所以我错了)?
第二个问题,如果这个表达式只适用于第一个八位位组,我如何将它应用到其他八位位组?对我来说,无法确定我正在处理哪个八位字节。因为,m 的值总是代表两个相反的八位字节。例如,如果 0<m<1
,则表示第 1 个和第 5 个八位字节。对吗?
第三,如何确定di的initial/starting值?
#include <iostream>
#include "utils.h"
void BresenhamLine(double x1, double y1, double x2, double y2, int color)
{
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
double x = x1;
double y = y1;
double dx = x2 - x1;
double dy = y2 - y1;
double dt = 2 * (dy - dx);
double ds = 2 * dy;
double d = 2*dy - dx;
PlotPixel(x, y, color);
if(dx>=dy)
{
while(x<=x2)
{
x++;
if(d<0)
{
d = d + ds;
}
else
{
y++;
d = d + dt;
}
PlotPixel(x, y, color);
}
}
else
{
while(y<=y2)
{
y++;
if(d<0)
{
x++;
d = d + dt;
}
else
{
d = d + ds;
}
PlotPixel(x, y, color);
}
}
}
int main()
{
int gm = DETECT;
int gd = DETECT;
initgraph(&gm, &gd, "");
double x1 = 0;
double y1 = 0;
double r = 50;
double x2 = 0;
double y2 = 0;
double signx = 0;
double signy = 0;
for(int theta=0 ; theta<=360 ; theta++)
{
x2 = r * cos(DegreeToRad((double) theta));
y2 = r * sin(DegreeToRad((double) theta));
x1 = 5 * cos(DegreeToRad((double) theta));
y1 = 5 * sin(DegreeToRad((double) theta));
BresenhamLine(x1, y1, x2, y2, YELLOW);
}
getch();
closegraph();
return 0;
}
穿过第 2 和第 4 象限的线未显示。
如何通过对我的代码进行一些小改动来解决这个问题?
有了这个输入:x1: 100 y1: -100 x2: -100 y2: 100
这个逻辑:
if(x1>x2 || y1>y2)
{
Swap(x1, x2);
Swap(y1, y2);
}
失败。
此页面是一个很好的起点。它还显示了 1 个八分圆的代码:
http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
我认为你需要交换 x
if x1 > x2
和交换 y
if y1 > y2
但不交换 both 如果其中只有一个为真。
Wikipedia page 的 外部链接 部分包含几个指向您可以研究的现成实现的链接。
试试这个:
void BresenhamLine( double x1, double y1, double x2, double y2, int color )
{
const bool steep = (std::abs(y2 - y1) > std::abs(x2 - x1));
if(steep)
{
std::swap(x1, y1);
std::swap(x2, y2);
}
if(x1 > x2)
{
std::swap(x1, x2);
std::swap(y1, y2);
}
double dx = x2 - x1;
double dy = std::abs(y2 - y1);
double error = dx / 2;
int ystep = (y1 < y2) ? 1 : -1;
int y = (int)y1;
int maxX = (int)x2;
for(int x=(int)x1; x<maxX; x++)
{
if(steep)
{
PlotPixel(y, x, color);
}
else
{
PlotPixel(x, y, color);
}
error -= dy;
if(error < 0)
{
y += ystep;
error += dx;
}
}
}
我通过稍微修改这里的代码得到这个:http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#C.2B.2B