// Interactive 2D Lagrange splines, Evgeny Demidov 22 June 2001 import java.awt.*; import java.awt.event.*; import java.util.StringTokenizer; public class @file extends java.applet.Applet implements MouseMotionListener{ Image buffImage; Graphics buffGraphics; int n = 4, n1, w,h,h1,w2; double[] Px,Py, ti; double bF[][]; public void drawFun(){ double step = 1./(w2-1), t = 0, min = 0, max = 0; Color[] iColor = {Color.red, new Color(0f,.7f,0f), Color.blue, Color.magenta, new Color(0f,.8f,.8f), new Color(.9f,.9f,0f), Color.gray }; buffGraphics.clearRect(0,0, w, h); for (int k = 0; k < w2; k++){ // basis functions calculation for (int j = 0; j < n; j++){ double P = 1; for (int i = 0; i < n; i++) if (i != j) P = P*(t-ti[i])/(ti[j] - ti[i]); if (P > max) max = P; if (P < min) min = P; bF[j][k] = P;} t += step;} // System.out.println("test"); double M = h1/(max-min); for (int j = 0; j < n; j++){ buffGraphics.setColor(iColor[j % 7]); for (int k = 1; k < w2; k++) buffGraphics.drawLine(w2+k-1, h1-(int)(M*(bF[j][k-1]-min)), w2+k, h1-(int)(M*(bF[j][k]-min)) );} int y0 = h1+(int)(M*min); buffGraphics.setColor(Color.black); buffGraphics.drawLine(w2,y0, w-1,y0); for (int i = 0; i < n; i++) buffGraphics.drawRect(w2+(int)(w2*ti[i])-1, y0-1, 3,3); } public void init() { w = Integer.parseInt(getParameter("width")); h = Integer.parseInt(getParameter("height")); h1 = h-1; w2 = w/2; String s = getParameter("N"); if (s != null) n = Integer.parseInt(s); n1 = n+1; Px = new double[n]; Py = new double[n]; ti = new double[n]; bF = new double[n][w2]; s=getParameter("pts"); if (s != null){ StringTokenizer st = new StringTokenizer(s); for (int i = 0; i < n; i++){ Px[i] = w2*Double.valueOf(st.nextToken()).doubleValue(); Py[i] = h1*Double.valueOf(st.nextToken()).doubleValue(); ti[i] = Double.valueOf(st.nextToken()).doubleValue();}} else{ Px[0] = .1*w2; Px[1] = .1*w2; Px[2] = .9*w2; Px[3] = .9*w2; Py[0] = .1*h1; Py[1] = .9*h1; Py[2] = .9*h1; Py[3] = .1*h1; ti[0] = 0; ti[1] = .33; ti[2] = .66; ti[3] = 1;} buffImage = createImage(w, h); buffGraphics = buffImage.getGraphics(); setBackground(Color.white); buffGraphics.clearRect(0,0, w, h); addMouseMotionListener(this); drawFun(); drawSpline(); } public void destroy(){ removeMouseMotionListener(this); } public void mouseMoved(MouseEvent e){} //1.1 event handling public void mouseDragged(MouseEvent e) { int y = h1 - e.getY(); if (y < 0) y = 0; if (y > h1) y = h1; int x = e.getX(); int iMin = 0; double Rmin = 1e10, r2,xi,yi; if ( x < w2){ if (x > w2-5) return; // if (x > w2-3) x = w2-3; if (x < 0) x = 0; for (int i = 0; i < n; i++){ xi = (x - Px[i]); yi = (y - Py[i]); r2 = xi*xi + yi*yi; if ( r2 < Rmin ){ iMin = i; Rmin = r2;}} Px[iMin] = x; Py[iMin] = y; } else{ double t = (double)(x - w2)/w2; if ( t > 1 ) t = 1; for (int i = 0; i < n; i++) if ( (r2 = Math.abs(ti[i]-t) ) < Rmin ){ iMin = i; Rmin = r2;} ti[iMin] = t; drawFun(); } drawSpline(); repaint(); } public void drawSpline(){ int X,Y; buffGraphics.clearRect(0,0, w2, h); buffGraphics.setColor(Color.blue); for (int i = 0; i < n; i++){ X = (int)Px[i]; Y = h1-(int)Py[i]; buffGraphics.drawRect(X-1,Y-1, 3,3);} if ( n > 2 ){ int Xo = (int)Px[0], Yo = h1-(int)Py[0]; for (int i = 1; i < n; i++){ X = (int)Px[i]; Y = h1-(int)Py[i]; buffGraphics.drawLine(Xo,Yo, X,Y); Xo = X; Yo = Y;} } buffGraphics.setColor(Color.red); double sX = 0, sY = 0; for (int j = 0; j < n; j++){ sX += Px[j]*bF[j][0]; sY += Py[j]*bF[j][0];} int Xold = (int)sX, Yold = h1-(int)sY; for (int k = 1; k < w2; k++){ sX = 0; sY = 0; for (int j = 0; j < n; j++){ sX += Px[j]*bF[j][k]; sY += Py[j]*bF[j][k];} X = (int)sX; Y = h1-(int)sY; if ( (X < w2) && (Xold < w2) ) buffGraphics.drawLine(Xold,Yold, X,Y ); Xold = X; Yold = Y; } } public void paint(Graphics g) { g.drawImage(buffImage, 0, 0, this); // showStatus( " " + x +" " + y); } public void update(Graphics g){ paint(g); } }