Ja.
Na ennyit a bevezetőről.
Tehát a képernyő egy nagyító alatti pontja megkapható: screen[x,y]:=bitmap[matr[x,y].x,matr[x,y].y];
És még csak most jön a java. Ugye egy ilyen a mátrixot a program elején egyszer kell kiszámolni. De ez nem olyan könnyű.
Egy módszer:
Mivel kör alakot akarunk nagyítani, ami a körön kívül
esik a mátrixban, azt nem kell bolygatni. Tehát a mátrixelem, saját pozícióját
fogja tartalmazni. (mint a példában a szélek)
if (x*x+y*y>r*r)
{
matr[x][y].x=x;
matr[x][y].y=y;
}
A probléma ott kezdődik, amikor a pont a körön belül van. Egy sík által félbevágott gömbbel egész jól lehet közelíteni a lencse torzítását:
Tehát , ha ki akarjuk számolni, hogy P pontban a nagyítón keresztül melyik pont fog látszani, akkor fel kell vetítenünk a gömbre, (Q pont) innen pedig egy egyenest kell húzni a gömb közepébe. Ahol az egyenes metszi a síkot, ott lesz a keresett pont. Hogy miért? Mert így működik!
Megkímélek mindenkit a képletek matamatikai levezetésétől, de ezen ábrák alapján le lehet.
Ix=x*d/(z+d);
Iy=y*d(z+d);
z=1+sqrt(d*d-x*x-y*y+r*r);
Ahol:
z : a felvetített pont magassága
d : a gömb középpontjának távolsáaga a síktól.
r : a lencse sugara
x,y : P pont koordinátái
Ix,Iy : I pont koordinátái
Ennek megfelelően:
void tabfill(int d,int r)
{
int x,y,z;
for(x=-LENRAD;x<LENRAD;x++)
for(y=-LENRAD;y<LENRAD;y++)
{
if (x*x+y*y=r*r) //bent van e a korben
{
z=sqrt(d*d-x*x-y*y+r*r)/3+1;
transtab[x+LENRAD][y+LENRAD].x=(x*d)/(z+d)+LENRAD;
transtab[x+LENRAD][y+LENRAD].y=(y*d)/(z+d)+LENRAD;
}
else //ha nincs, akkor marad
{
transtab[x+LENRAD][y+LENRAD].x=x+LENRAD;
transtab[x+LENRAD][y+LENRAD].y=y+LENRAD;
}
}
}
A cuccos ki van számolva.
Ennyi maga az effekt:
void len(int x, int y)
{
int n,m;
x-=LENRAD;
y-=LENRAD;
for(n=0;n<2*LENRAD;n++)
for(m=0;m<2*LENRAD;m++)
{
if(x+n>0 && x+n<320 && y+m>0
&& y+m<200)
screen[x+n+(y+m)*320]=pic[x+transtab[n][m].x+(y+transtab[n][m].y)*320];
}
}
Na ennyi.
A forráskód Watcom C-ben sikerült.