/* 頂点変形 ImageFilter Ver 0.00 */ /* */ /* */ /* by Atsushi 98/5/7 */ package net.antun.lib.awt.image; import java.awt.Dimension; import java.awt.image.ColorModel; public class TransformationImageFilter extends SinglepassImageFilter { /* --- Field --- */ private int width,height; private int px0,py0,px1,py1,px2,py2,px3,py3; private int ox,oy; private int ax,ay,bx,by,cx,cy,dx,dy; /* --- Constructor --- */ public TransformationImageFilter(int px0,int py0,int px1,int py1, int px2,int py2,int px3,int py3) { this.px0=px0;this.py0=py0; this.px1=px1;this.py1=py1; this.px2=px2;this.py2=py2; this.px3=px3;this.py3=py3; ax=px0 ;ay=py0 ; bx=px1-px0 ;by=py1-py0 ; cx=px2-px0 ;cy=py2-py0 ; dx=px3-px1-px2+px0;dy=py3-py1-py2+py0; } /* --- フィルタリング --- */ public void setDimensions(int width,int height) { int maxWidth,maxHeight; super.setDimensions(width,height); maxWidth =Math.max(Math.max(px0,px1),Math.max(px2,px3)); maxHeight=Math.max(Math.max(py0,py1),Math.max(py2,py3)); ox=-Math.min(Math.min(px0,px1),Math.min(px2,px3)); oy=-Math.min(Math.min(py0,py1),Math.min(py2,py3)); this.width =ox+maxWidth; this.height=oy+maxHeight; consumer.setDimensions(this.width,this.height); } protected void filterImage() { int xx,yy,p[]; double a,b,c,u,v,nx,ny; p=new int[width]; for (int y=0;y<=height-1;y++) { for (int x=0;x<=width-1;x++) { // x-ox=ax+bx*xx+cx*yy+dx*xx*yy // y-oy=ay+by*xx+cy*yy+dy*xx*yy a=dy*bx-dx*by; b=cy*bx+dy*ax-cx*by-dx*ay-dy*(x-ox)+dx*(y-oy); c=cy*ax-cx*ay-cy*(x-ox)+cx*(y-oy); if (a==0) { u=(-c)/b; v=(-c)/b; } else { u=(-b-Math.sqrt(b*b-4.0*a*c))/(2.0*a); v=(-b+Math.sqrt(b*b-4.0*a*c))/(2.0*a); } if (cx+dx*v==0.0 && cy+dy*v==0.0) { nx=u; if (cy+dy*u==0.0) { ny=((x-ox)-ax-bx*u)/(cx+dx*u); } else { ny=((y-oy)-ay-by*u)/(cy+dy*u); } } else { nx=v; if (cy+dy*v==0.0) { ny=((x-ox)-ax-bx*v)/(cx+dx*v); } else { ny=((y-oy)-ay-by*v)/(cy+dy*v); } } if (Double.isNaN(nx) || Double.isNaN(ny)) { xx=-1; yy=-1; } else { xx=(int)(originalSize.width *nx); yy=(int)(originalSize.height*ny); } if (0<=xx && xx<=originalSize.width -1 && 0<=yy && yy<=originalSize.height-1) { p[x]=original[xx+yy*originalSize.width]; } else { p[x]=0; } } consumer.setPixels(0,y,width,1,defaultRGB,p,0,width); } } public void setHints(int hint) { consumer.setHints(TOPDOWNLEFTRIGHT | COMPLETESCANLINES | SINGLEPASS | (hint & SINGLEFRAME)); } /* --- 文字列化 --- */ public String toString() { StringBuffer param=new StringBuffer(); param.append("point="); param.append("("+px0+","+py0+"),"); param.append("("+px1+","+py1+"),"); param.append("("+px2+","+py2+"),"); param.append("("+px3+","+py3+")"); return getClass().getName()+"["+param+"]"; } }