Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


Эфект линзы

Поиск:
  Реализация 1 - на Паскале.

Если линза на экpане - окpужность (x0,y0,r0), то в точках (x,y), для котоpых (x-x0)2+(y-y0)2<=r02,pисуется точка, котоpая, если бы линзы не было, изобpажалась бы в точке (x0+(x-x0)*k1,y0+(y-y0)*k), где k=const1 / ([sqrt]((x-x0)2+(y-y0)2) + const2). Можно заpанее пpосчитать таблицу смещений - array[-r0..r0,-r0..r0] of intege

Код

{$A+,B-,D+,E+,F-,G+,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}

{$M 16384,0,655360}

Uses CRT;

Const vx0 = 3;
      vy0 = 2;
      v0  = vx0;
      r0  = 50;
      r02 = (r0-v0)*(r0-v0);
      d   = r02 * 10 div 10;
Type ScreenType = Array[0..199,0..319] of Byte;
     DispType   = Array[-r0..r0,-r0..r0] of Integer;

Var

    Screen           : ScreenType Absolute $a000:$0000;
    Buffer1, Buffer2 : ^ScreenType;
    Disp             : ^DispType;
    x,y,vx,vy,r2,c   : LongInt;
Procedure Move(Var A,B; Count: Word);
assembler;
asm
        push ds
        mov  cx, Count
        les  di, B
        lds  si, A
        shr  cx, 1
        jz   @zero
        rep  movsw
@zero:  pop  ds
end;
BEGIN

asm
  mov ax, $13
  int $10
end;

New(Buffer1);
New(Buffer2);
New(Disp);

FillChar(Screen, SizeOf(Screen), 3);
y:=0;

repeat

  For x:=0 to 319 do Screen[y,x]:=11;
  Inc(y,10);

until y>199;

x:=0;

repeat

  For y:=0 to 199 do Screen[y,x]:=11;
  Inc(x,10);

until x>319;

Move(Screen, Buffer1^, SizeOf(Screen));
Move(Buffer1^,Screen,64000);

For y:=-r0 to r0 do
For x:=-r0 to r0 do
  begin

  r2:=x*x+y*y;
  if r2>r02 then Disp^[y,x] := y*320+x
   else
  Disp^[y,x]:=(y*(r2+d)div(r02+d))*320+(x*(r2+d)div(r02+d));

  end;

x:=r0;
y:=r0;
vx:=vx0;
vy:=vy0;
repeat

  asm
          mov     ax, Integer(y)
          mov     bx, 320
          imul    bx
          add     ax, Integer(x)
          mov     di, ax
          mov     dx, -r0*320-r0
          les     si, Disp
          mov     ch, 2*r0+1
@next_dy: mov     cl, 2*r0+1
@next_dx:
          mov     es, Word(Disp+2)
          mov     bx, es:[si]
          mov     es, Word(Buffer1+2)
          mov     al, es:[di+bx]
          mov     bx, Seg(Screen)
          mov     es, bx
          mov     bx, dx
          mov     es:[di+bx], al
          add     si, 2
          inc     dx
          dec     cl
          jnz     @next_dx
          add     dx, 320-(2*r0+1)
          dec     ch
          jnz     @next_dy
  end;

  if ((x+vx)>=r0)and ((x+vx)<=319-r0)then Inc(x, vx)
                                       else vx:=-vx;

  if ((y+vy)>=r0)and ((y+vy)<=199-r0)then Inc(y,vy)
                                       else vy:=-vy;
  Delay(25);
until Port[$60]=$01;

Dispose(Buffer1);
Dispose(Buffer2);
Dispose(Disp);

asm
  mov ax, $03
  int $10
end;

END.




Реализация 2 - на Watcom C.

Пусть у нас есть матрица , которую нужно преобразовать. То есть у нас есть какой-то прямоугольный массив, который мы хотим показать в линзе. Итак у нас есть исходная матрица. Каждая пара координат в матрице (I,J) переходит в новую пару координат (X,Y). Формулу смотрите в исходнике. Тогда элемент матрицы с новыми координатами (X,Y) становиться равным смещению в матрице, которое соответствует координатам (I,J). Это первый этап, для дальнейшего ускорения вывода , расчитаем еще два массива. Один массив - это смещения по которому мы берем значение цвета точки. А второй массив - смещения по которым мы этот цвет будет ставить. Тогда весь вывод линзы сведеться к циклу, в котором мы берем точку по одному смещению , а ставим по другому.

Код

#include <stdio.h>
#include <math.h>

#define PI      3.1415926
#define max     40

char bmp[64000];
char Scr[64000];
char p[1024];
int  matr[2*max][2*max];
int  glassnew[2*max][2*max];
int  glassold[2*max][2*max];

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

// Wait Ret Race #################################################
void wait_retrace()
{
  while ((inp(0x3DA) & 0x08) == 0);
  while ((inp(0x3DA) & 0x08) != 0);
}

// PutPixel ######################################################
void PutPixel(int x,int y,int Color)
{
   if ((x>0)&&(y>0)&&(x<320)&&(y<200)) Scr[x+y*320]=Color;
}

// GetPixel ######################################################
int GetPixel(int x,int y)
{
   return(bmp[x+y*320]);
}

void main(void)
{
  FILE *f;
  int i,j,xc,yc,c,yc1,xc1,foffset;
  float s,x,y,a,b;

  setvmode(0x13);
  f=fopen("1.bmp", "rb");
  fseek(f,1024+54,0);
  fread(&bmp, 1, 64000, f);
  fseek(f,54,0);
  fread(&p, 1, 1024, f);
  fclose(f);

  // Готовим палитру
  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);
   }
   // Создаем таблицу переходов
   for (i=-max;i<max;i++)
   for (j=-max;j<max;j++)
    {
     s=sin(PI/2+(PI/2)/(max*2.2)*sqrt(i*i+j*j));
     x=(i*s);
     y=(j*s);
     glassnew[i+max][j+max]=(int)x+(int)y*320;
     glassold[i+max][j+max]=(i/2)+(j/2)*320;
    }
  do {
   memcpy((char*)&Scr, (char*)&bmp, 64000);
   xc=160+100*cos(2*a)*sin(b);
   yc=100+70*cos(b);
   foffset=xc+yc*320;
   for (i=0;i<2*max;i++)
   for (j=0;j<2*max;j++)
    {
     Scr[foffset+glassnew[i][j]]=bmp[foffset+glassold[i][j]];
    }
//   wait_retrace();
   memcpy((char*)0xA0000L, (char*)&Scr, 64000);
   a=a+0.01;
   b=b+0.01;
  } while (!kbhit());
  getch();
  setvmode(0x03);
}
Сайт: www.rudocs.com






Просмотров: 2286

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную