Алгоритм имитации бьющегося стилизованного сердца

heart.JPG

Реализовать алгоритм имитации бьющегося сердца. Воспользоваться прерыванием 10h для включения графического режима под ОС DOS. Dыполнить заливку сердца и градиент.

Для реализации алгоритма построим параметрический график функции, который будет задавать "границу" сердца. Занесем полученные точки в массивы.
x(t)= a * cos(t)^3
y(t)= - (sin(t) + b*cos(2*t))
После чего реализуем функцию заливки, которая будет проходить по всем х-координатам начиная со следующей, и, находя равную, - проводить линию. Непосредственно в функции рисования линии создадим реализацию градиента.
Процесс движения реализуем в два этапа - наращивание будет происходить за счёт дорисовки большего сердца, сокращение - за счёт создания чёрного контура.

#include <math.h>
#include <dos.h>
#include <conio.h>
float t,x,y;
float xr,yr;
int i,k,z,w,j;
int a[1050];
int b[1050];
 
unsigned char far *screen = (unsigned char far *) 0xA0000000;
 
//вызываем прерывание 10h
void SetMode (unsigned short mode) {
  asm {
     mov ax, [mode]
     int 0x10
  }
}
 
//установка точки на экран
void putpixel (int x, int y, int color)
{
	screen[y * 320 + x] = color;
	return;
}
 
//установка палитры
void setpallette (unsigned char c,unsigned char r,
		  unsigned char g,unsigned char b)
{
   outp (0x3c6,0xff);
   outp (0x3c8,c);
   outp (0x3c9,r);
   outp (0x3c9,g);
   outp (0x3c9,b);
}

При помощи следующей функции мы построим прямую, параллельную оси ординат. Поскольку другие в данной задаче нам не потребуются, то будет достаточно рассмотреть только такой тип. В этой же функции мы реализуем градиент, разделив линию на три равные части, крайние из которых будут постепенно изменять свой цвет, а средняя будет иметь постоянное значение.

void line (int x1, int y1, int y2){
     int re
 
s = x1;
     int maxy, miny, y13,y23,dy;
     int color = 16;
 
     if (y1 > y2) {miny = y2;maxy = y1;dy = y1-y2;}
     else { miny = y1; maxy = y2;dy = y2-y1;}
 
     while (miny <= maxy){
	   y13 = maxy - dy + dy/3;
	   y23 = maxy - dy + 2*dy/3;
	   if (miny < y13) color+=2;
	   if (miny > y23) color-=2;
	   putpixel(res,miny,color);
	   miny++;
     }
}
 
//зарисовка сердца чёрным цветом
void black(float rad, float xr, float yr){
   for (t = -5,i = 0; t <= 5; t = t + 0.01,i++) {
       x = -xr * cos(t) * cos(t) * cos(t);
       y = - ( sin(t) + yr * cos(2 * t));
       a[i] = 410 + rad * x;
       b[i] = 300 + rad * y;
       putpixel(a[i],b[i],0);
   }
}

В функции heart мы находим точки, которые будут являться "границей" сердца. Полученные точки будем заносить в массивы. Параметр loop будет определять размер сердца, параметры xr, yr искривление по осям абсцисс и ординат соответственно.

void heart(float loop,float xr, float yr){
  for (t = -5,i = 0; t <= 5; t = t + 0.01,i++) {
       x = -xr * cos(t) * cos(t) * cos(t);
       y = - ( sin(t) + yr * cos(2 * t));
       a[i] = 410 + loop * x;
       b[i] = 300 + loop * y;
  }
}
 
//построение сердца, заливка
void view(){
  for (z = 0;z <= i;z++){
	  for (w =z+1; w<= i;w++)
	      if (a[z] == a[w]){
	      line(a[z],b[z],b[w]);
	      break;
	   }
  }
}
 
 
int main(){
 
   SetMode(0x13);
 
   for(int i = 1; i<64; i++)
     setpallette(i,i,0,0);
 
   int n = 90;
   float s = 30; 
   float p = 1.65; 
   float q = 0.7;
 
 
  while(!kbhit()){
    while (1){
	heart(s,p,q);
	view();
	delay(n);
	s++; 
	if (s == 35) break;
     }
 
     while (1){
	heart(s,p,q);
	view();
	delay(n);
	black(s,p,q);
	 s--;
	 if (s == 30) break;
    }
  }
 
   return 0;
}

Ключевые слова: 
Сердце, кардиоида, изменение палитры, градиент, заливка, биение
ВложениеРазмер
heart.rar18.8 кб