:: алгоритмы  и методы :: :: олимпиадные задачи :: :: связь :: :: о сайте ::
Путь: Графика » Эффекты » Скручивание
  Скручивание



Эта реализация не слишком отличается от эффекта линза, единственное отличие - по другой формуле расчитывается таблица.


#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

#define PI      3.1415926
#define FILTERW 120
#define FILTERH 120
#define FILTERW_2 (FILTERW/2)
#define FILTERH_2 (FILTERH/2)

int FILTER_W=FILTERW;
int FILTER_H=FILTERH;
double sp_Amp=2*PI;
double sp_Pow=6;

char bmp[64000];
char p[1024];
int filter[FILTERW*FILTERH];

extern void setvmode(int);
#pragma aux setvmode = \
  " int 10h " \
  parm [eax] \
  modify exact [eax];

void wait_retrace() {
  while ((inp(0x3DA) & 0x08) == 0);
  while ((inp(0x3DA) & 0x08) != 0);
}

void fload() {
  FILE *f;

  if ((f=fopen("1.bmp", "rb")) == NULL)
   {
    printf("error: file %s not found.\n 1.bmp");
    exit(1);
   }
  fseek(f,1024+54,0);
  if (fread(&bmp, 1, 64000, f)!=64000)
   {
    printf("error: can't read data from %s.\n 1.bmp");
    exit(1);
   }
  fclose(f);
  if ((f=fopen("1.bmp", "rb")) == NULL)
   {
    printf("error: file %s not found.\n 1.bmp");
    exit(1);
   }
  fseek(f,54,0);
  if (fread(&p, 1, 1024, f)!=1024)
   {
    printf("error: can't read data from %s.\n 1.bmp");
    exit(1);
   }
  fclose(f);
}

void apply_filter(char *dst, char *src, int *filter, int x, int y) {
  int i, j, o = x + 320 * y, *f = filter;
  char *d = dst + o, *s = src + o;

  for (i = 0; i < FILTERW; i++) {
    for (j = 0; j < FILTERH; j++) *d++ = *(s++ + *f++);
    d += (320 - FILTERW);
    s += (320 - FILTERW);
  }
}

void make_filter() {
  int i, j, i1, j1, v;
  double r, a, t0, t1;

  for (i = 0; i < FILTERW; i++)
    for (j = 0; j < FILTERH; j++) {
      r = sqrt(((double)i / FILTERW - 0.5) 
        * ((double)i / FILTERW - 0.5) +
        ((double)j / FILTERH - 0.5) * ((double)j / FILTERH - 0.5));
      if (r < 0.5) {
 a = sp_Amp * pow(1 - 2 * r, sp_Pow);
 i1 = (i - FILTERW_2) * cos(a) - (j - FILTERH_2) * sin(a) +
   FILTERW_2 - i;
 j1 = (i - FILTERW_2) * sin(a) + (j - FILTERH_2) * cos(a) +
   FILTERH_2 - j;
 v = i1 + j1 * 320;
      } else v = 0;
      filter[i + FILTERW * j] = v;
    }
}

void main () {
  int i = 0, x, y, f = 0, t;
  char c;

  make_filter();
  fload();
  setvmode(0x13);
  for(i=0;i<256;i++)
   {
    outp(0x3C8,i);
    outp(0x3C9,p[(i*4)+2] >> 2);
    outp(0x3C9,p[(i*4)+1] >> 2);
    outp(0x3C9,p[(i*4)+0] >> 2);
   }

  do {
    x = (1 + cos ((double)f / 13)) * (160 - FILTERW_2);
    y = (1 + sin ((double)f / 23)) * (100 - FILTERH_2);
    wait_retrace();
    wait_retrace();
    memcpy((char*)0xA0000L, (char*)&bmp, 64000);
    apply_filter((char*)0xA0000L, (char*)&bmp, (int*)&filter, x, y);
    f++;
    c = kbhit() ? getch() : 0;
  } while (c != 0x1B);
  setvmode(0x03);
  printf(" Coded by Misha Krivij");}