Реализовать алгоритм имитации плазмы. Рассмотрим способ построения плазмы с помощью рекурсивного задания портрета самой плазмы и дальнейшего изменения ее цветов по соответствующим уравнениям гармонических колебаний (таким образом,обеспечив плавность переходов цвета): for (i=0;i<=170;i++){ pal[3*i]=(63* sin( ( (double)i/170.0) *M_PI) ); pal[3*i+256]=(63*sin((double)i/170.0*M_PI)); pal[(3*i+512)%768]=floor(63*sin((double)i/170*M_PI)); Здесь pal-массив,хранящий палитру(с помощью него мы будем ее задавать) сам портрет плазмы строится таким образом: В программе использована "прямая" работа с видеорежимом 13h ,320x200 px,256 colors Исходный код на Си: #include <stdio.h> #include <dos.h> #include <stdlib.h> #include <conio.h> #include <graphics.h> #include <math.h> #include <iostream.h> #pragma comment(linker,"/STACK:32777216") char Get (int x,int y); void Set(int x,int y,char color); unsigned char pal[769]; int ncol(int m,int n,int d) { int loc; loc=(m+n-random(n))/d; if (loc>255) return 255; if (loc<0) return 0; return loc; } void drawp(int x1,int y1,int x2,int y2) { int xn,yn,dxy,p1,p2,p3,p4; if ((x2-x1<2)&&(y2-y1<2)) return; p1=Get(x1,y1); p2=Get(x1,y2); p3=Get(x2,y1); p4=Get(x2,y2); xn=(x1+x2)/2; yn=(y1+y2)/2; dxy=3*(x2-x1+y2-y1)/4; if (Get(xn,y1)==0) Set(xn,y1,ncol(p1+p3,dxy,2)); if (Get(x1,yn)==0) Set(x1,yn,ncol(p1+p2,dxy,2)); if (Get(x2,yn)==0) Set(x2,yn,ncol(p3+p4,dxy,2)); if (Get(xn,y2)==0) Set(xn,y2,ncol(p2+p4,dxy,2)); Set(xn,yn,ncol(p1+p2+p3+p4,dxy,4)); drawp(x1,y1,xn,yn); drawp(xn,y1,x2,yn); drawp(x1,yn,xn,y2); drawp(xn,yn,x2,y2); return; } char Get (int x,int y) { char color; asm{ push di mov cx,x mov dx,y mov bl,color mov ax,0xA000 mov es,ax mov ax,320 mul dx add ax,cx mov di,ax mov bl,es:[di] mov color,bl pop di; } return color; } void Set(int x,int y,char color) { asm { push di mov cx,x mov dx,y mov bl,color mov ax,0xA000 mov es,ax mov ax,320 mul dx add ax,cx mov di,ax mov es:[di],bl pop di } } void init() { int i=0; for (i=0;i<16000*4;i++) Set(i%320,i/320,0); } int main() { randomize(); asm MOV AX,13h; asm INT 10h; int cnt=0; int iterator; int i; for (i=0;i<=170;i++){ pal[3*i]=(63* sin( ( (double)i/170.0) *M_PI) ); pal[3*i+256]=(63*sin((double)i/170.0*M_PI)); pal[(3*i+512)%768]=floor(63*sin((double)i/170*M_PI)); } drawp(0,0,319,199); while(!kbhit()) { do while((inport(0x03DA)&&8)==0); while((inport(0x03DA)&&8)==8); delay(10); outport(0x3C8,cnt); asm{ MOV SI,offset pal MOV CX,769 MOV DX,0x3C9 REP outsb } cnt++; } getch(); ;asm MOV AX,3h; asm INT 10h; return 0; } Исходный код на Turbo Pascal: {$A+,B-,D+,E+,F-,G+,I-,L+,N-,O-,P-,Q-,R-,S-,T-,V+,X+,Y+} uses crt; var i : integer; counter : byte; pal : array[0..768]of byte; screen : array[0..63999]of byte absolute $A000:0; function col(a,b,dvd : integer): integer; var loc : integer; begin loc:=(a+b-random(b)) div dvd; col:=loc; if loc>255 then col:=255; if loc<0 then col:=0 end; procedure plasma(x1,y1,x2,y2 : integer); var xn,yn,dxy,p1,p2,p3,p4 : integer; begin if (x2-x1<2) and (y2-y1<2) then EXIT; p1:=screen[320*y1+x1]; p2:=screen[320*y2+x1]; p3:=screen[320*y1+x2]; p4:=screen[320*y2+x2]; xn:=(x2+x1) div 2; yn:=(y2+y1) div 2; dxy:=(x2-x1+y2-y1); if screen[320*y1+xn]=0 then screen[320*y1+xn]:=col(p1+p3,dxy,2); if screen[320*yn+x1]=0 then screen[320*yn+x1]:=col(p1+p2,dxy,2); if screen[320*yn+x2]=0 then screen[320*yn+x2]:=col(p3+p4,dxy,2); if screen[320*y2+xn]=0 then screen[320*y2+xn]:=col(p2+p4,dxy,2); screen[320*yn+xn]:=col(p1+p2+p3+p4,dxy,4); plasma(x1,y1,xn,yn); plasma(xn,y1,x2,yn); plasma(x1,yn,xn,y2); plasma(xn,yn,x2,y2) end; begin asm mov ax,13h int 10h end; for i:=1 to 170 do pal[3*i]:=round(63*sin(i/170*pi)); for i:=1 to 170 do pal[3*i+256]:=round(63*sin(i/170*pi)); for i:=1 to 170 do pal[(3*i+512) mod 768]:=round(63*sin(i/170*pi)); plasma(1,1,319,199); counter:=0; repeat delay(2000); port[$3C8]:=counter; asm mov si,offset pal mov cx,768 mov dx,$3C9 rep outsb end; inc(counter); until keypressed; asm mov ax,3h int 10h end; end.
Ключевые слова:
плазма, изменение палитры, режим 13h, цвет
|
|||||||||