Алгоритм имитации плазмы

plasma.jpg

Реализовать алгоритм имитации плазмы.

Далее будет рассмотрен алгоритм имитации плазмы основанный на функции синуса.

Палитра.

Для придания нашим волнам особого объема, построим палитру особым образом. Первые 128 цветов будут идти по возрастанию, оставшиеся 128 - по убыванию. При задании новой палитры мы можем получить новые эффекты.

Функция синуса.

Наша плазма будет основываться на синусоидах идущих в диапазоне от -1 до 1 и проходящих 0 как середину. Ширина одной волны равна 360*.

Плазма.

Точка плазмы на экране будет задаваться суммой трех следующих функций:

  • sin(x * PI/270) * 256 (Рис. 1.1.)
  • sin(y * PI/ 45) * 256/8 (Рис. 1.2.)
  • sin(y+x+o * PI/ 90) * 256/4 (Рис. 1.3.)

, где o - параметр, а последний множитель - количество цветов. Результирующая функция будет выглядеть следующим образом:

f(x,y,o) = sin(x * PI/270) * 256 + sin(y * PI/ 45) * 256/8 + sin(y+x+o * PI/ 90) * 256/4 (Рис. 1.4.)

Также реализован эффект сглаживания (Рис. 2.2), который можно посмотреть нажав "Enter".

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
 
#define ENTER_KEY 13
#define ESC_KEY   27
 
#define VGA_SCREEN 0xa000
#define VIDEO_INT  0x10
#define VGA_MODE   0x13
#define TXT_MODE   0x03
 
#define DAC_WRITE_INDEX 0x03c8
#define DAC_DATA_REG    0x03c9
 
#define PSIN \ /* точка плазмы по ф-и синуса */
sin((x)     *M_PI / 270) *256/1 + \
sin((y)     *M_PI /  45) *256/8 + \
sin((y+x+o) *M_PI /  90) *256/4   \
 
#define PCOS \ /* точка плазмы по ф-и косинуса */
cos((x)     *M_PI / 270) *256/1 + \
cos((y)     *M_PI /  45) *256/8 + \
cos((y+x+o) *M_PI /  90) *256/4   \
 
unsigned char far *screen; // 
unsigned int effect = 0;
 
void set_mode (int);
void set_palette ();
void pset (int,int,unsigned int);
 
// графический режим
void set_mode (int mode) {
  union REGS regs;
  regs.x.ax = mode;
  int86(VIDEO_INT,&regs,&regs);
}
 
// ставим точку на экране
void pset (int x, int y, unsigned int c){ screen[y*320+x]=c; }
 
// загружаем палитру
void set_palette () {
  int i;
  for (i=0; i<256; i++) {
      outportb(DAC_WRITE_INDEX, i);
      outportb(DAC_DATA_REG,200); // 235,200
      outportb(DAC_DATA_REG,((i>127)?(255-i):(i)));
      outportb(DAC_DATA_REG,0);
    }
}
 
// Прорисовываем плазму...
int main () {
  printf("Press 'Enter' to change the effect. Any key to continue..."); getch();
 
  char key = ' ';
 
  // Выставляем графический режим...
  set_mode(VGA_MODE);
  screen = (char far *)MK_FP(VGA_SCREEN, 0);
  // Загружаем палитру...
  set_palette();
 
  int y,x;
  int o,k,c,t;
 
  k=1;
  o=0;
 
  while (key != ESC_KEY) {
     o+=k;
     if (o>600||o< -600) k=-k; // обеспечиваем движение плазмы вниз и вверх
     for (y=0; y<200; y++)
       for (x=0; x<320; x++) {
	 t=PSIN; // выбираем ф-ю по которой будем ставить точку на экране
	 if (effect) t>>=3;
	 pset(x,y,t);
       }
 
     if (kbhit()) {
       key = getch();
 
       if (key == ENTER_KEY) // смена эффекта
	effect ^=1;
     }
 
   }
 
  // Возврат графического режима...
  set_mode(TXT_MODE);
  return 0;
}

Ключевые слова: 
плазма, изменение палитры, режим 13h, цвет
ВложениеРазмер
Plasma.rar19.85 кб