media @ VU
applet-math-nurbs.jva
applet-math-nurbs.jva
/ applet-math-nurbs
// Interactive 2D NURBS, Evgeny Demidov 10 August 2001
import java.awt.*;
import java.awt.event.*;
import java.util.StringTokenizer;
public class applet-math-nurbs extends java.applet.Applet
implements MouseMotionListener{
Image buffImage; Graphics buffGraphics;
int n=1, k=2, n1, nt, Tmin,Tmax, w,h,h1,w2;
double[] Px,Py,wi, ti;
double N[][];
Color[] col, iColor = {Color.red, new Color(0f,.7f,0f), Color.blue,
Color.magenta, new Color(0f,.8f,.8f), new Color(.9f,.9f,0f), Color.gray };
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){
StringTokenizer st = new StringTokenizer(s);
n = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());}
n1 = n+1;
nt = n+k+1;
Px = new double[n1]; Py = new double[n1]; wi = new double[n1];
ti = new double[nt+k];
col = new Color[w2];
N = new double[nt+1][w2];
s=getParameter("pts");
if (s != null){
StringTokenizer st = new StringTokenizer(s);
for (int i = 0; i < n1; i++){
Px[i] = w2*Double.valueOf(st.nextToken()).doubleValue();
Py[i] = h1*Double.valueOf(st.nextToken()).doubleValue();
wi[i] = Double.valueOf(st.nextToken()).doubleValue();}}
else{
Px[0] = .2*w2; Px[1] = .8*w2; Py[0] = .8*h1; Py[1] = .2*h1;
wi[0] = 1; wi[1] = 1;}
s=getParameter("knots");
if (s != null){
StringTokenizer st = new StringTokenizer(s);
for (int i = 0; i < nt; i++)
ti[i] = Double.valueOf(st.nextToken()).doubleValue();}
else{ ti[0] = 0; ti[1] = 1; ti[2] = 2; ti[3] = 3; }
double to = ti[0], dt = ti[nt-1]-to;
for (int i = 0; i < nt; i++) ti[i] = w2 + w2*(ti[i]-to)/dt;
buffImage = createImage(w, h);
buffGraphics = buffImage.getGraphics();
setBackground(Color.white);
buffGraphics.clearRect(0,0, w, h);
addMouseMotionListener(this);
Fun(); 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-10) return;
if (x < 0) x = 0;
for (int i = 0; i < n1; 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{
if ( x > w ) x = w - 1;
if ( e.isShiftDown() ){
for (int i = 0; i < nt; i++)
if ( (r2 = Math.abs(ti[i]-x) ) < Rmin ){ iMin = i; Rmin = r2;}
ti[iMin] = x;
Fun();}
else wi[(n1*(x - w2))/w2] = y*5./h1;
drawFun();}
drawSpline();
repaint();
}
public void Fun(){
double step = (ti[nt-1]-ti[0])/(w2-.9), t = ti[0];
Tmin = (int)((ti[k-1]-ti[0])/step) + 1;
Tmax = (int)((ti[n1]-ti[0])/step);
int i1 = 0;
for (int l = 0; l < w2; l++){
while (t >= ti[i1] ) i1++;
int i = i1-1;
col[l] = iColor[(i+8-k) % 7];
for (int j = 0; j < nt; j++) N[j][l] = 0;
N[i][l] = 1;
for (int m = 2; m <= k; m++){
int jb = i-m+1; if (jb < 0) jb = 0;
for (int j = jb; j <= i; j++){
// System.out.println("m=" + m + " j=" + j +" i=" + i+" l="+l);
N[j][l] = N[j][l]*(t - ti[j])/(ti[j+m-1] - ti[j]) +
N[j+1][l]*(ti[j+m] - t)/(ti[j+m] - ti[j+1]);}}
t += step;}
}
public void drawFun(){
double step = (ti[nt-1]-ti[0])/(w2-.9), t;
buffGraphics.clearRect(0,0, w, h);
for (int j = 0; j < n1; j++){
buffGraphics.setColor(iColor[j % 7]);
t = ti[0];
int to = (int)t;
for (int l = 1; l < w2; l++){
t += step;
int t1 = (int)t;
buffGraphics.drawLine(to, h1-(int)(h1*N[j][l-1]),
t1, h1-(int)(h1*N[j][l]) );
to = t1;}}
for (int l = k; l <= n1; l++){
buffGraphics.setColor(iColor[(l-k) % 7]);
buffGraphics.drawLine((int)ti[l-1], 1, (int)ti[l], 1);}
buffGraphics.setColor(Color.black);
for (int l = 0; l < nt; l++)
buffGraphics.drawRect((int)ti[l]-1, 0, 3,3);
int xo = w2 + (int)(w2*.5/n1);
for (int l = 0; l < n1; l++){
buffGraphics.setColor(iColor[l % 7]);
buffGraphics.drawRect(xo+l*w2/n1, h1-(int)(h1*wi[l]/5.), 3,3);}
}
public void drawSpline(){
int X,Y;
buffGraphics.clearRect(0,0, w2, h);
buffGraphics.setColor(Color.blue);
for (int i = 0; i < n1; i++){
X = (int)Px[i]; Y = h1-(int)Py[i];
buffGraphics.drawRect(X-1,Y-1, 3,3);}
if ( k > 2 ){
int Xo = (int)Px[0], Yo = h1-(int)Py[0];
for (int i = 1; i < n1; i++){
X = (int)Px[i]; Y = h1-(int)Py[i];
buffGraphics.drawLine(Xo,Yo, X,Y);
Xo = X; Yo = Y;}
}
double sX = 0, sY = 0, sW = 0;
for (int j = 0; j < n1; j++){
sX += Px[j]*wi[j]*N[j][Tmin]; sY += Py[j]*wi[j]*N[j][Tmin];
sW += wi[j]*N[j][Tmin]; }
int Xold = (int)(sX/sW), Yold = h1-(int)(sY/sW);
for (int k = Tmin+1; k <= Tmax; k++){
sX = 0; sY = 0; sW = 0;
for (int j = 0; j < n1; j++){
sX += Px[j]*wi[j]*N[j][k]; sY += Py[j]*wi[j]*N[j][k];
sW += wi[j]*N[j][k]; }
X = (int)(sX/sW); Y = h1-(int)(sY/sW);
buffGraphics.setColor(col[k]);
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); }
}
(C) A. Eliëns
2/9/2007
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.