Есть для С четыре варианта: [Из FAQ "draw_line.c"] [+]
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено megajohn 22 ноября 2006 г. 17:08
В ответ на: А никто не кинет в меня масенькой библиотечкой рисования линий и дуг на AVRовском ASMе..? Был бы очень признателен! :) отправлено <font color=gray>MaxVovk</font> 22 ноября 2006 г. 16:51


Подскажите функцию или алгоритм рисования линии. Чтобы не изобретать велосипед
from:http://www.telesys.ru/wwwboards/mcontrol/1453/messages/355594.shtml
void DrawLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned char pixel)
{
int idata x, y, d, dx, dy, i, i1, i2, kx, ky;
char idata flag;

dx = x2 - x1;
dy = y2 - y1;
if (dx == 0 && dy == 0) PutPixelXY(x1, y1, pixel);
else
{
kx = 1;
ky = 1;
if( dx < 0 )
{
dx = -dx;
kx = -1;
}
else
if(dx == 0) kx = 0;
if(dy < 0)
{
dy = -dy;
ky = -1;
}
if(dx < dy)
{
flag = 0;
d = dx;
dx = dy;
dy = d;
}
else flag = 1;
i1 = dy + dy;
d = i1 - dx;
i2 = d - dx;
x = x1;
y = y1;

for(i=0; i < dx; i++)
{
PutPixelXY(x, y, pixel);
if(flag) x += kx;
else y += ky;
if( d < 0 ) d += i1;
else
{
d += i2;
if(flag) y += ky;
else x += kx;
}
}
PutPixelXY(x, y, pixel);
}
}

Параметр Pixel в вызове определяет как рисовать пикселы...
Если 1, то пикселами темными на светлом фоне, если 0 - то наоборот (инверсное изображение линии)...


Вариант №2 (Брезенхем)
void drawline(int x1, int y1, int x2, int y2)
{
int x;
int y;
int dx;
int dy;
int sx;
int sy;
int z;
int e;
int i;
int ch;

x = x1;
y = y1;
dx = abs(x2-x1);
dy = abs(y2-y1);
sx = sign(x2-x1);
sy = sign(y2-y1);
e = 2*dy-dx;
if( dy>=dx )
{
z = dx;
dx = dy;
dy = z;
ch = yes;
}
else
{
ch = no;
}
i = 1;
do
{
lcd_setpixel(x, y);
if( e {
if( ch == yes)
{
y = y+sy;
}
else
{
x = x+sx;
}
e = e+2*dy;
}
else
{
if( ch == yes)
{
x = x+sx;
}
else
{
y = y+sy;
}
e = e-2*dx;
}
i = i+1;
}
while(i<=dx+dy);
lcd_setpixel(x, y);
}

Вариант №3
void GL_DrawLine1(int x0, int y0, int x1, int y1) {
int xdiff = x1-x0;

int ydiff = y1-y0;
int xdiffby2;
int i;
char Swapped =0;


/* check if no line */
if (!(xdiff|ydiff)) {
GL_DrawPoint(x0,y0);
return;
}

#if 0
/* check if horizontal line */
if (!xdiff) {
GL_DrawVLine(x0,y0,y1);
return;
}
/* check if vertical line */
if (!ydiff) {
GL_DrawHLine(y0,x0,x1);
return;
}
#endif

/* check if we swap x and y for calculation */
if (Abs(xdiff) < Abs(ydiff)) {
GL_SwapInt(&xdiff,&ydiff);
GL_SwapInt(&x0,&y0);
GL_SwapInt(&x1,&y1);
Swapped =1;
}
/* make sure line direction is positive */
if (xdiff!=Abs(xdiff)) {
xdiff = -xdiff;
ydiff = -ydiff;
GL_SwapInt(&x0,&x1);
GL_SwapInt(&y0,&y1);
}
xdiffby2 = xdiff/2;
if (ydiff<0)
xdiffby2 = -xdiffby2;
/* Draw pixel by pixel solid*/
if (GUI_Context.LineStyle == GUI_LS_SOLID) {
for (i=0; i<=xdiff; i++) {
I32 l = ((I32)ydiff)*i+xdiffby2;
int y = (ABS(l)<32767) ? (y0 + ((int)l)/xdiff) : (y0 + l/xdiff);
if (!Swapped)
LCD_HL_DrawPixel(x0+i, y);
else
LCD_HL_DrawPixel(y, x0+i);
}
/* Draw pixel by pixel with fill style */
} else {
for (i=0; i<=xdiff; i++) {
long l = ((long)ydiff)*i+xdiffby2;
int y = (ABS(l)<32767) ? (y0 + ((int)l)/xdiff) : (y0 + l/xdiff);
if (!SetLineColor(i)) {
if (!Swapped)
LCD_HL_DrawPixel(x0+i, y);
else
LCD_HL_DrawPixel(y, x0+i);
}
}
}
}

Вариант №4
/*-------------------------------------*/
/*
x,y - начальные координаты
dx,dy - разность координат, а не ширина в пикселах
dx = x2-x1
dy = y2-y1
color - 1/0 чертить/стирать Глобальный флаг для point

Использовался "маленький" дисплей - все координаты уместились в byte
*/
void line (byte x, byte y, signed char dx, signed char dy)
{
byte add_x =1, add_y =1;
byte m_l, n_l;
byte sum_l;
byte count_l;

if (dx < 0) {dx=-dx; add_x = -1;}
if (dy < 0) {dy=-dy; add_y = -1;}

++ dx;
++ dy;

sum_l=0;
if (dx >= dy)
{
m_l = dx / dy; /* частное */
n_l = dx % dy; /* остаток */

for(;;)
{
count_l = m_l;
do
{
point (x,y);
x += add_x;
if (--dx == 0) return;
}while(--count_l);

sum_l +=n_l;
if (sum_l >= dy)
{
sum_l -= dy;
point (x,y);
x += add_x;
if (--dx == 0) return;
}
y += add_y;
}

}
else
{
m_l = dy / dx; /* частное */
n_l = dy % dx; /* остаток */

for (;;)
{r
count_l = m_l;
do
{
point (x,y);
y += add_y;
if (--dy == 0) return;
}while(--count_l);

sum_l +=n_l;
if (sum_l >= dx)
{
sum_l -= dx;
point (x,y);
y += add_y;
if (--dy == 0) return;
}
x += add_x;
}
}

}


Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа
Имя (обязательно): 
Пароль: 
E-mail: 

Тема (обязательно):
Сообщение:

Ссылка на URL: 
URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание