直线段的矢栅转换算法(DDA算法、中心画线算法、Bresenham算法)
以下为drawLine.cpp,分别对相应的原理进行了注释,只需调用相应的函数即可实现。
#include "drawLine.h"
#include "setPixel.h"
#include "cmath"
void DDALine ( int x0, int y0, int x1, int y1) {
float x= x0, y= y0;
float dx= x1- x0;
float dy= y1- y0;
float xadd, yadd;
int step;
if ( abs ( dx) > abs ( dy) ) {
step= abs ( dx) ;
float yadd= ( float ) dy/ ( float ) step;
float xadd= ( x1 - x0) > 0 ? 1 : - 1 ;
for ( int i= 0 ; i<= step; i++ ) {
setPixel ( x, int ( y+ 0.5 ) ) ;
y= y+ yadd;
x= x+ xadd;
}
}
else {
step= abs ( dy) ;
yadd= ( y1 - y0) > 0 ? 1 : - 1 ;
xadd= ( float ) dx/ ( float ) step;
for ( int i= 0 ; i<= step; ++ i) {
setPixel ( int ( x+ 0.5 ) , int ( y) ) ;
y= y+ yadd;
x= x+ xadd;
}
}
}
void swap_value ( int & a, int & b) {
int temp= a;
a= b;
b= temp;
}
void midpoint_line ( int x0, int y0, int x1, int y1) {
int a, b, d2, x, y, flag = 0 ;
if ( abs ( x1 - x0) < abs ( y1 - y0) )
{
swap_value ( x0, y0) ;
swap_value ( x1, y1) ;
flag = 1 ;
}
if ( x0 > x1) {
swap_value ( x0, x1) ;
swap_value ( y0, y1) ;
}
a = y0 - y1;
b = x1 - x0;
d2 = 2 * a + b;
if ( y0 < y1) {
x = x0; y = y0;
setPixel ( x, y) ;
while ( x < x1)
{
if ( d2 < 0 )
{
x++ ;
y++ ;
d2 = d2+ 2 * a + 2 * b;
}
else {
x++ ;
d2 = d2+ 2 * a;
}
if ( flag)
setPixel ( y, x) ;
else
setPixel ( x, y) ;
}
}
else {
x = x1;
y = y1;
setPixel ( x, y) ;
while ( x > x0)
{
if ( d2 < 0 ) {
x-- ;
y++ ;
d2 = d2- 2 * a + 2 * b;
}
else {
x-- ;
d2 = d2- 2 * a;
}
if ( flag)
setPixel ( y, x) ;
else
setPixel ( x, y) ;
}
}
}
void Bresenham_line1 ( int x0, int y0, int x1, int y1) {
int dx = x1 - x0;
int dy = y1 - y0;
int ux = dx > 0 ? 1 : - 1 ;
int uy = dy > 0 ? 1 : - 1 ;
int dx2 = abs ( dx << 1 ) ;
int dy2 = abs ( dy << 1 ) ;
if ( abs ( dx) > abs ( dy) )
{
int e = - dx;
int x = x0;
int y = y0;
while ( x!= x1+ ux)
{
setPixel ( x, y) ;
e = e + dy2;
if ( e > 0 )
{
if ( y!= y1)
{
y + = uy;
}
e = e - dx2;
}
x + = ux;
}
}
else
{
int e = - dy;
int x = x0;
int y = y0;
while ( y!= y1+ uy)
{
setPixel ( x, y) ;
e = e + dx2;
if ( e > 0 )
{
if ( x!= x1)
{
x + = ux;
}
e = e - dy2;
}
y + = uy;
}
}
}
void Bresenham_line ( int x0, int y0, int x1, int y1
) {
setPixel ( x0, y0) ;
int dx, dy;
int flag= 0 ;
dx = abs ( x1- x0) ;
dy = abs ( y1- y0) ;
if ( dx == 0 && dy == 0 )
return ;
if ( dy > dx)
{
flag = 1 ;
swap_value ( x0, y0) ;
swap_value ( x1, y1) ;
swap_value ( dx, dy) ;
}
int tx = ( x1 - x0) > 0 ? 1 : - 1 ;
int ty = ( y1 - y0) > 0 ? 1 : - 1 ;
int curx = x0 + 1 ;
int cury = y0;
int dS = 2 * dy;
int dT = 2 * ( dy- dx) ;
int d = dS- dx;
while ( curx != x1)
{
if ( d >= 0 ) {
d + = dT;
cury + = ty;
}
else {
d + = dS;
}
if ( flag)
setPixel ( cury, curx) ;
else
setPixel ( curx, cury) ;
curx+ = tx;
}
}
void draw_line ( int x0, int y0, int x1, int y1)
{
DDALine ( x0, y0, x1, y1) ;
}