/* metacircle morphing by using Bezier Clipping by T.N '97 11/17 modified on 97' 11/15, morph(11/20), mesh(11/23) */ import java.applet.Applet; import java.awt.*; import java.io.*; import java.net.URL; import java.util.StringTokenizer; /* *********************************************************: */ public class circmor extends Applet { Point[] p = new Point[10]; Point[] p1 = new Point[10]; Point PntC; int n = 0; int Nc=4; int ndiv = 100; int disp_con = 1; int disp_mod = 0; int curve1=0; double Rmax=300.; double TOLEL= 0.005; int multi = 0; int Ncurve=-1; double tintt; int nsplit=0,n_clip=0,iproces; Button b1,b2,b3,b4,b5; Choice cmod = new Choice(); Choice cn1 = new Choice(); //cn1に項目の追加 Choice cn2 = new Choice(); Panel p3 = new Panel(); Label l1,l6; TextField t1; Point prev = new Point(0, 0); int idrag=0; double select_u=-1.; Curve3[] Bez=new Curve3[10]; Curve3[] Bez_back=new Curve3[10]; Curve3[] Bez1=new Curve3[10]; Curve3[] Bez_s=new Curve3[10]; Curve3[] Bez_d=new Curve3[10]; int closestCurv=0; double DISmin=100000.; Point closestPnt = new Point(0,0); int x_origin,y_origin; double scale=1.; int view_chang=1; int findp=0; int itest =1; int MAXdeg = 20; double[][] binom = new double[MAXdeg][MAXdeg]; int idebug=0;int nbar=0; int addcirc=0; int ncirc=0,ncirc_s=0,ncirc_d=0; Metaball metaball[]; Metaball metaball_s[]; Metaball metaball_d[]; Vec2 circp[][]; Vec2 circp_s[][]; Vec2 circp_d[][]; int inc_circ=0; String datafile=" "; double xcenter= 0., ycenter = 0.; double half1 = 0.7; int fill_crc=0; int disp_anime=0; int morph=0; int cores[]; int Nmesh=0,Mmesh=0,mesh_move=0; /* **************************************************************: */ public void init() { String str; Dimension appsize; setBackground(new Color( 140, 140,150)); setForeground(Color.red); appsize = size(); setLayout(new BorderLayout(0,0)); CheckboxGroup gc = new CheckboxGroup(); Checkbox c2= new Checkbox("add",gc, true); Checkbox c1= new Checkbox("deform",gc, false); Panel p = new Panel(); p.setBackground(new Color(40,40,125)); p.add(b1 = new Button("New Curve")); p.add(b2 = new Button("Add Curve")); p.add(new Label("Mode;")); p.add(c1);p.add(c2); p.add(b3 = new Button("dbg")); add("South",p); //cmodに項目の追加 cmod.addItem("Input Mode"); cmod.addItem("HourceData"); cmod.addItem("TigerData"); cmod.addItem("CircleFill"); cmod.addItem("Clear"); cmod.addItem("Animation"); cmod.addItem("Data Print"); cmod.addItem("Mesh"); // Choice cn1 = new Choice(); //cn1に項目の追加 cn1.addItem("degree 3 Bezier Curve"); cn1.addItem("degree 4 Bezier Curve"); cn1.addItem("degree 5 Bezier Curve"); cn1.addItem("degree 6 Bezier Curve"); cn1.addItem("degree 7 Bezier Curve"); cn1.addItem("degree 8 Bezier Curve"); //p3に項目の追加 p3.setBackground(new Color(40,40,125)); p3.add(cmod); p3.add(cn1); // p3.add(l6 = new Label("R=")); // p3.add(t1 = new TextField("100",3)); p3.add(b4 = new Button("back")); p3.add(b5 = new Button("morph")); Checkbox d2= new Checkbox("test"); p3.add(d2); add("North",p3); metaball = new Metaball[500]; circp = new Vec2[500][5]; if ((str = getParameter("disp_mod")) != null) { disp_mod= Integer.parseInt(str) ; } resize(350,340); showStatus("Click Draw bottun!"); x_origin = appsize.width/2; y_origin = appsize.height/2; binit(18); } /* *************** 描画関数 *****************************: */ public void paint(Graphics g) { int i,ix; //,nint=0 // int ndeg1=4; if(idrag==0) { g.setColor(Color.yellow); for(i = 0; i < n; i++) g.fillOval(p[i].x-3, p[i].y-3, 7, 7); if(n>1) {g.setColor(Color.black); for(i = 1; i < n; i++) g.drawLine(p[i-1].x,p[i-1].y,p[i].x,p[i].y); } } if(Nmesh>0) meshDisp(g); if(ncirc>0) { circDisp(g); } //円の描画 if(morph >= 2) {preMorp(g); return;} // モーフイング if(Ncurve>0 ) { if(idrag==0 || findp==0) { for(int k=0;k0) { for(int k=0;k120.) { // System.err.println("k="+k+" ball="+i_ball+" u="+circp[i_ball][k].u+" r="+circp[i_ball][k].v+" f="+f); // System.err.println("ball="+i_ball+" u="+circp[i_ball][k].u+" x="+P0.y+" y="+P0.z); // System.err.println("x="+x+" y="+y); // g.drawLine((int)x+x_origin, (int)y+y_origin, (int)P0.y+x_origin, (int)P0.z+y_origin); } // if(k==1) {g.setColor(Color.gray); // g.fillOval((int)x+x_origin-1, (int)y+y_origin-1, 2, 2);} // else {g.setColor(Color.green); // g.fillOval((int)x+x_origin-1, (int)y+y_origin-1, 4, 4);} /* System.err.println("p1x="+p2[0].x+"p1y="+p2[0].y); System.err.println("P1x="+P3[0].x+"P1y="+P3[0].y); */ // System.err.println("xorg="+x_origin+" yorg="+y_origin); // System.err.println("a="+a+" b="+b+" c="+c+" d="+d+" f="+f); } } /* **************************************************************: */ public void DispData(int k,Graphics gr) { gr.setColor(Color.black); for(int i=0;i0) g.drawString("Curve="+Cnum+" u= "+xint[0] +" d_min="+dist+ " x="+Pwrd.y+" y="+Pwrd.z+" z="+Pwrd.x,20,44+12*Cnum); else g.drawString(" u= "+xint[0] +" d_min="+dist+ " x="+Pwrd.y+" y="+Pwrd.z+" z="+Pwrd.x,20,44+12*Cnum); */ // closestPnt = new Point((int)xint[1]+C.x,(int)xint[2]+C.y); if(xint[0]<0.01 || xint[0]>0.99) { showStatus("u="+xint[0]+" distance="+Math.sqrt(xint[3])+ " Number of split="+ nsplit+" clip="+n_clip+" iterations="+nbar);} } // " Number of split="+ nsplit+" clip="+n_clip+" u="+u_min); } return new Point((int)xint[1]+C.x,(int)xint[2]+C.y); // 最近点の2次元座標を返す } /* ***********サンプリイング法で距離を算出 **************: */ public Point clospnt2(int ndeg,Point pnt1[],double xint[],Graphics g) { Point PntQ= new Point(0,0); double r2,u_min=0.; int i; double dismin2=100000.; for( i=0; i <= ndiv; i++){ double u = (double)i /(double)ndiv; Point current = castljau(u,ndeg,pnt1); r2= (double)current.x*current.x+ current.y*current.y; if(r2 0.0001) iposi = 1; else if(cf[i] < -0.0001) inega = 1; } //System.err.println(" cf="+cf[0]+", "+cf[1]+", "+cf[2]+", "+cf[3]); if(iposi == 0) { return (-1);} /* all negative means : dont't overlap */ if(inega != 0) { /* (+ + + +) */ if(root3(ndeg, span, cf,tlr)<0) {return (-1);} //System.err.println(" tlr="+tlr[0]+", "+tlr[1]); } inega = 0; iposi = 0; for(i=0;i<=ndeg; i++){ cf[i] = (-a*x1[i] - b*y1[i])/w1[i] + dist; if(cf[i] > 0.0001) iposi = 1; else if(cf[i] < -0.0001) inega = 1; } //System.err.println(" cf="+cf[0]+", "+cf[1]+", "+cf[2]+", "+cf[3]); if(iposi == 0) { return (-1);} /* all negative means : dont't overlap */ if(inega != 0) { /* (+ + + +) */ if(root3(ndeg, span, cf,tlr)<0) {return (-1);} // System.err.println(" tlr="+tlr[0]+", "+tlr[1]); } double tmp= t1[0]; t1[0]=tmp+(t1[1]-tmp)*tlr[0]; t1[1]=tmp+(t1[1]-tmp)*tlr[1]; // lr_split(ndeg,x1,y1,tlr[0],1.-tlr[1]); n_clip++ ; lr_Split(ndeg,x1,y1,w1,tlr[0],1.-tlr[1]); n_clip++ ; for(i=0; i < ndeg; i++) { x2[i] = x1[i+1]/w1[i+1]-x1[i]/w1[i]; y2[i] = y1[i+1]/w1[i+1]-y1[i]/w1[i];} //x2[i] = x1[i+1]-x1[i]; y2[i] = y1[i+1]-y1[i];} if(disp_con==0){ g.setColor(Color.yellow); for(i=0;i0) {xint[3] = dismin2; xint[0]=u_min;} return nint; } /* ********************************************************************: */ int s_ovrlp(int ndeg,double x1[],double y1[],double w1[],double t1[],double x2[],double y2[], double xint[],int nint,Graphics g) { double[] x1l= new double[20]; double[] y1l= new double[20]; double[] t1l= new double[2]; double[] x1r= new double[20]; double[] y1r= new double[20]; double[] t1r= new double[2]; double[] w1l= new double[20]; double[] w1r= new double[20]; int i,iover; iover = ovrlp(ndeg,x1,y1,w1,t1,x2,y2, xint,g); if(disp_con==0){// debug時 プロット g.setColor(Color.green); if(iover==0) g.setColor(Color.darkGray); if(iover==1) g.setColor(Color.white); for(i=1; i 20) return 0; // subdiv(ndeg,x1,y1, x1l,y1l, x1r,y1r,0.5,t1,t1l,t1r); //System.err.println(" ovlp;t0="+t1[0]+" t1="+t1[1]+"ndeg="+ndeg); subDiv(ndeg,x1,y1,w1,x1l,y1l,w1l,x1r,y1r,w1r,0.5,t1,t1l,t1r); for(i=0; i < ndeg; i++) { x2[i] = x1l[i+1]/w1l[i+1]-x1l[i]/w1l[i]; y2[i] = y1l[i+1]/w1l[i+1]-y1l[i]/w1l[i];} nint=s_ovrlp(ndeg,x1l,y1l,w1l,t1l,x2,y2, xint,nint,g); for(i=0; i < ndeg; i++) { x2[i] = x1r[i+1]/w1r[i+1]-x1r[i]/w1r[i]; y2[i] = y1r[i+1]/w1r[i+1]-y1r[i]/w1r[i];} nint=s_ovrlp(ndeg,x1r,y1r,w1r,t1r,x2,y2,xint,nint,g); } else if(iover == 2) { //再度よぶ // System.err.println(" iover=2"); nint=s_ovrlp(ndeg,x1,y1,w1,t1,x2,y2, xint,nint,g); } return nint; } /* ************************************************************: */ void plotrange(double t1[], int index,Graphics g) { int length =300,ybar=295,ybar1; // if(index==0) {nbar=0; return;} nbar++; if(nbar>30) System.err.println("Test:nbar="+nbar); if(idebug==0 && disp_mod==0) return; ybar1=ybar-nbar; g.setColor(Color.yellow); if(nbar%10==0) g.setColor(Color.orange); g.drawLine(10,ybar1,10+length,ybar1); g.setColor(Color.red); g.drawLine(10+(int)(length*t1[0]),ybar1,10+(int)(length*t1[1]),ybar1); } /* ************************************************************: */ int ovrlp(int ndeg,double x1[],double y1[],double w1[],double t1[], double x2[],double y2[],double xint[], Graphics g) /* Checks the overlap of the two curve segments return = 0 for no overlap (=no intersections) = -1 for inadequate clip (split each curve and try again) = 1 for intersection found */ { double tmp1, tmp2, ur22; double ur11, tl2,ur2,tl1, ur1; double d1,d2,d,dd,dmin,dmax,a=0.,b=1.; int i,icount,jover=0; double[] t2 = new double[2]; plotrange(t1,1,g); // test if(itest==0) { int indQ = bmul1(x1,y1,w1,x2,y2,ndeg); if(indQ==1) return 0;} // 極値はない if(itest==1) { int indQ = bmul3(x1,y1,w1,x2,y2,ndeg,t2,t1,0,g); if(indQ==1) return 0; // 極値はない if(idebug==1) System.err.println("Q ="+indQ+" t="+t1[0]+", "+t1[1] +" clip="+n_clip+" split="+nsplit); ur22 = 1. - t2[1]; tl2=t2[0]; ur2=t2[1]; tmp2 = t1[0] + tl2*(t1[1]-t1[0]); tmp1 = t1[1] + ur22*(t1[0]-t1[1]); lr_Split(ndeg,x1,y1,w1,tl2,ur22); n_clip++ ; t1[0]=tmp2; t1[1]=tmp1; if(idebug==1) System.err.println(" aft g;lr_S; t10=" + t1[0]+",t1="+t1[1]+ " delt="+(tmp1-tmp2)+" tl2="+tl2+" ur2="+ur2); if((tmp1-tmp2)< TOLEL) { if(disp_mod==0|| disp_mod==1) {g.setColor(Color.blue); if(tl2>0.02 || ur22>0.02) { lr_Split(ndeg,x1,y1,w1,tl2,ur22); n_clip++ ;//clipping } double r2 = (x1[0]*x1[0]+y1[0]*y1[0])/w1[0]/w1[0]; if(r20.30 || dmin<-0.30) { return -1;} //分割必要 if(dmax>0.70 || dmin<-0.70) { if(t1[1]-t1[0]>0.1) return -1;} //分割必要 if(t1[1]-t1[0]<0.035) { // 無理やりサンプリング法で判定 int ndiv1 = (int)((t1[1]-t1[0])/0.005)+1; if(ndiv1>20) ndiv1=20; int nint= caldismin(ndeg,x1,y1,w1,xint,ndiv1,g); if(nint>0) { xint[0]= (t1[1]-t1[0])*xint[0]+t1[0]; System.err.println(" caldismin u="+xint[0]+" x="+xint[1]+" r2="+xint[3]+ " ndiv="+ndiv1+" t0="+t1[0]+" t1="+t1[1]); if(disp_mod==0){ g.setColor(Color.yellow); g.drawLine(PntC.x, PntC.y,(int)xint[1]+PntC.x,(int)xint[2]+PntC.y);} return 1; } } if(t1[1]-t1[0]<0.0001) {System.err.println(" t1<0.0005??");return 0;} t2[0]=0.; t2[1]=1.; iproces=0; for(icount=0; icount< 20; icount ++) { iproces++; if(iproces>1)return 0; /* curve-x1 is clip by curve-x2 */ jover = hull(ndeg,x1,y1,w1,x2,y2,a,b,aa,bb,t2,g); //ウエッジで分割範囲を判定 if(jover < 0) return -1; if(jover == 1) return -1; if(jover == 2) return -1; ur22 = 1. - t2[1]; tl2=t2[0]; ur2=t2[1]; tmp2 = t1[0] + tl2*(t1[1]-t1[0]); tmp1 = t1[1] + ur22*(t1[0]-t1[1]); t1[1] = tmp1; t1[0] = tmp2; if((tmp1-tmp2)< TOLEL) { if(disp_mod==0) {g.setColor(Color.white); for(int k=0;k 0.) && (cf[nmdeg] < 0.) ) /* (+ ? ? -) > right cut [0,tmax] */ { tmax = 0. ; /* do 310 */ for (i=0; i < nmdeg; i++) { if(cf[i] > 0.) { for(j= i+1 ; j <= nmdeg; j++) { if(cf[j] < cf[i]) { if(cf[j] < 0.) { t = (cf[i]/(cf[i]-cf[j])*(double)(j-i)+i)*span; if(t > tmax) tmax = t; } } } } } if(tmax != 0.) { if(tlr[0] > tmax+.000001) return (-1) ; if(tlr[1] > tmax) tlr[1] = tmax;} } else if( (cf[0] < 0.) && (cf[nmdeg] > 0.) ) /* (- ? ? +) > left cut [tmin,1.] */ { tmin = 1. ; /* do 320 */ for(i=0; i < nmdeg; i++) { if(cf[i] < 0.) { for(j=i+1; j <= nmdeg ; j++) { if(cf[j] > cf[i]) { if(cf[j] > 0.) { t = (cf[i]/(cf[i]-cf[j])*(double)(j-i)+i)*span ; if(t < tmin) tmin = t ; } } } } } if(tmin != 1.) { if(tlr[1] < tmin-0.000001) return (-1) ; if(tlr[0] < tmin) tlr[0] = tmin; } } else if( (cf[0]> 0) && (cf[nmdeg] > 0.) ) { } /* split 1/2 */ else if( (cf[0] < 0.) && (cf[nmdeg] < 0.)) /* (- ? ? -) > both side cut [tmin,tmax] */ { tmax = 0. ; /* do 330 */ for(i=1; i < nmdeg; i++) { for(j=i+1; j <= nmdeg; j++) { if( (cf[i] > 0.) && (cf[j] < 0.)) { t = (cf[i]/(cf[i]-cf[j])*(double)(j-i)+i)*span ; if(t > tmax) tmax = t ; } } } if(tmax != 0) { if(tlr[0] > tmax+.000001) return (-1) ; if(tlr[1] > tmax) tlr[1] = tmax ; } tmin = 1. ; /* do 340 */ for(i=0; i < nmdeg-1; i++) { for(j=i+1; j < nmdeg; j++) { if((cf[i] < 0) && (cf[j] > 0.)) { t = (cf[i]/(cf[i]-cf[j])*(double)(j-i)+i)*span ; if(t < tmin) tmin = t; } } } if(tmin != 1.) { if(tlr[1] < tmin-0.000001) return (-1) ; if(tlr[0] < tmin) tlr[0] = tmin ; } } return (0) ; } /* ***********サンプリング法で距離を算出 **************: */ public Point clospnt1(int ndeg,Point pnt[], Point C, Graphics g) { Point PntQ= new Point(0,0); Point[] pnt1 = new Point[20]; double r2,u_min=0.; int i; double[] xint1= new double[4]; for( i=0; i <=ndeg; i++) { pnt1[i] = new Point(pnt[i].x-C.x,pnt[i].y-C.y);} PntQ = clospnt2(ndeg,pnt1,xint1,g); // showStatus(" min_distance="+Math.sqrt(dismin2)+" u="+u_min); return new Point(PntQ.x+C.x,PntQ.y+C.y); } /* *************** 描画関数(塗りつぶし)*****************: */ /* public void Bezscan(int ndeg,Point pnt[],Graphics g) { int i,ix,nint=0; double[] xint = new double[4]; // xint[0]=u,xint[1]=x,xint[2]=y,xint[3]=distance double[] xint1= new double[4]; Point C; Point PntQ= new Point(0,0); Point[] pnt1 = new Point[11]; Point[] pnt2 = new Point[10]; double r2,u_min=0.; double[] t1= new double[2]; double[] x1= new double[11]; double[] y1= new double[11]; double[] x2= new double[10]; double[] y2= new double[10]; double[] w1= new double[10]; if(Rmax>40) Rmax=40; int ymax=0; int ymin=320; int xmax=0; int xmin=320; for(i=0;i<=ndeg;i++){ if(pnt[i].y < ymin) ymin=pnt[i].y; if(pnt[i].y > ymax) ymax=pnt[i].y; if(pnt[i].x < xmin) xmin=pnt[i].x; if(pnt[i].x > xmax) xmax=pnt[i].x; } System.err.println(" ymin="+ymin+", ymax="+ymax); System.err.println(" xmin="+xmin+", xmax="+xmax); int ymin1 = ymin-45; if(ymin1<20) ymin1=20; int xmin1 = xmin-55; if(xmin1<1) xmin1=1; int ymax1 = ymax+60; if(ymax1>349) ymax1=349; int xmax1 = xmax+55; if(xmax1>338) xmax1=338; for(int iy=ymin1;iyRmax*Rmax) { dismin2=Rmax*Rmax;xint[0]=-1.;} xint[3]=dismin2; nsplit = 0; nint = 0; n_clip = 0;nbar=0; t1[0] = 0.0; t1[1] = 1.0; nint = d_ovrlp(ndeg,x1,y1,w1,t1,x2,y2,xint,g); // 前処理:距離でクリップ if(nint<0) {break;} nint = s_ovrlp(ndeg,x1,y1,w1,t1,x2,y2,xint,nint,g); // g.setColor(Color.white); if(xint[0]<0) { // select_u=-1.; PntQ = clospnt2(ndeg,pnt1,xint1,g); g.setColor(Color.gray); if(xint1[3]=i; j--) { x[j] = x[j] + (x[j-1] - x[j])*ur; y[j] = y[j] + (y[j-1] - y[j])*ur; } } /* ***************** 曲線の右クリップ ****************************: */ void rsplit(int ndeg,double x[],double y[],double tl) { int i,j; for(i=1; i <= ndeg; i++) { for(j=0; j <= ndeg-i; j++) { x[j] = x[j] + (x[j+1] - x[j])*tl; y[j] = y[j] + (y[j+1] - y[j])*tl; } } } /* *****************曲線の左右クリップ*************************: */ public void lr_split(int ndeg,double x[],double y[],double tl,double ur){ double tmp; rsplit(ndeg,x,y,tl); if(ur == 0.) return; tmp = ur/(1.0-tl); lsplit(ndeg,x,y,tmp); } /* *****************曲線の左右クリップ*************************: */ public void lr_Split(int ndeg,double x[],double y[],double w[], double tl,double ur){ double tmp; rSplit(ndeg,x,y,w,tl); if(ur < 0.00005) return; tmp = ur/(1.0-tl); lSplit(ndeg,x,y,w,tmp); } /* ******************** 曲線の左クリップ ****************************************: */ public void lSplit(int ndeg,double x[],double y[],double w[],double ur){ int i,j; for(i=1; i<= ndeg; i++) for(j=ndeg; j>=i; j--) { x[j] = x[j] + (x[j-1] - x[j])*ur; y[j] = y[j] + (y[j-1] - y[j])*ur; w[j] = w[j] + (w[j-1] - w[j])*ur; } } /* ***************** 曲線の右クリップ ****************************: */ void rSplit(int ndeg,double x[],double y[],double w[],double tl) { int i,j; for(i=1; i <= ndeg; i++) { for(j=0; j <= ndeg-i; j++) { x[j] = x[j] + (x[j+1] - x[j])*tl; y[j] = y[j] + (y[j+1] - y[j])*tl; w[j] = w[j] + (w[j+1] - w[j])*tl; } } } /* **************************************************************: */ public boolean mouseDown(Event evt, int x, int y) { if(n < Nc && addcirc==0){ p[n] = new Point(x,y); n++; }else{ n=0; } if(addcirc==1 && idrag==0) { if(y<260) {ncirc++; inc_circ=1; metaball[ncirc] = new Metaball((double)x,(double)y,0.,0.,1.); showStatus(" set Point = "+ncirc+" x="+x+" y="+y); } } prev = new Point(x, y); repaint(); return true; } /* ---------------------------------------------------------------------- */ public boolean mouseDrag(Event ev, int x, int y) { int ix,iy,id; if(findp==1) { double[] x1 = new double[10];double[] y1=new double[10]; ix = x-prev.x; iy = y-prev.y; if(ix==0 && iy==0) return true; if( iy>295) return true; for(int i=0;i1-1./(double)Nc*0.2) id=Nc-1; id = (int)(select_u*(double)(Nc-1)+0.4); if(id>Nc) id = Nc-1; if(select_u<1./(double)Nc*0.2) id=0; if(select_u>1-1./(double)Nc*0.2) id=Nc-1; int iix = ix; int iiy=iy; x1[id]=1.; Point2 current = castljau2(select_u,Nc-1,x1,y1); if(current.x<0.25) current.x=0.25; double xx = ((double)ix/current.x); double yy = ((double)iy/current.x); Point3 Dp = new Point3(0,xx,yy); // System.err.println("Dp x="+Dp.x+" y="+Dp.y+" z="+Dp.z+"xx="+xx+"yy="+yy); // xx = Dp.y; yy =Dp.z; Bez[closestCurv].P3[id] = new Point3(Bez[closestCurv].P3[id].x+Dp.x, Bez[closestCurv].P3[id].y+Dp.y,Bez[closestCurv].P3[id].z+Dp.z); Bez[closestCurv].p3[id] = tranfrm(Bez[closestCurv].P3[id]); showStatus("Curv #="+closestCurv+" Moving Point= "+id+" u="+select_u+" scal="+(1./current.x)); idrag=1; repaint(); prev.move(x, y); } if(addcirc==1) { ix = Math.abs(x-prev.x); iy = Math.abs(y-prev.y); id= ix; if(ix