/* SCCS - @(#)TemporaryBezier.java 1.6 - 09/01/99 - 00:15:51 */ //-------------------------------------- // $Log: TemporaryBezier.java,v $ // // Revision 1.1 1998/02/02 23:52:39 erhan // TemporaryBezier & etc // // Revision 1.4 1997/05/09 22:30:23 danjie // add some comments and Log // //-------------------------------------- /* *Copyright(c)1997 USC Brain Project. email nsl@java.usc.edu */ package nslj.src.display; import java.lang.*; import java.awt.*; import java.util.*; import java.io.*; import nslj.src.lang.*; import nslj.src.system.*; import java.lang.Math; public class TemporaryBezier extends NslCanvas { private Vector2 priv=new Vector2(); public void TemporaryBezier() { end = new Vector2(); } public Vector2 V2SubII(Vector2 a, Vector2 b) { Vector2 c=new Vector2(); c.xset( a.xval() - b.xval() ); c.yset( a.yval() - b.yval() ); return(c); } /* * ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent : *Approximate unit tangents at endpoints and "center" of digitized curve */ public Vector2 ComputeLeftTangent(Vector2 [] d, int end) /* d; Digitized points*/ /* end; Index to "left" end of region */ { Vector2 tHat1; tHat1 = V2SubII(d[end+1], d[end]); //tHat1 = V2Normalize(tHat1); //System.out.println("end "+end+" d[end+1] "+d[end+1].xval()+" "+d[end+1].yval()+" d[end] "+d[end].xval()+" "+d[end].yval()+" IN LEFT TANGENT:"+tHat1.xval()+" "+tHat1.yval() ); tHat1.V2Normalize(); //--System.out.println("IN LEFT TANGENT:"+tHat1.xval()+" "+tHat1.yval() ); return tHat1; } public Vector2 ComputeRightTangent(Vector2 [] d, int end) /* d; Digitized points */ /* end; Index to "right" end of region */ { Vector2 tHat2; tHat2 = V2SubII(d[end-1], d[end]); //tHat2 = V2Normalize(tHat2); tHat2.V2Normalize(); //--System.out.println("IN RIGHT TANGENT:"+tHat2.xval()+" "+tHat2.yval() ); return tHat2; } public Vector2 ComputeCenterTangent(Vector2 [] d, int center) /* d; Digitized points */ /*center; Index to point inside region */ { Vector2 V1, V2, tHatCenter; V1 = V2SubII(d[center-1], d[center]); V2 = V2SubII(d[center], d[center+1]); tHatCenter = new Vector2(); tHatCenter.xset ( (V1.xval() + V2.xval() )/2.0); tHatCenter.yset ( (V1.yval() + V2.yval() )/2.0); tHatCenter.V2Normalize(); return tHatCenter; } /* * ChordLengthParameterize : * Assign parameter values to digitized points * using relative distances between points. */ public double [] ChordLengthParameterize(Vector2 [] d, int first, int last) /* *d; Array of digitized points */ /* first, last; Indices defining region */ { int i; double [] u; /* Parameterization */ //--System.out.println("ENTERING ChordLengthParametrize"); u = new double [last-first+1]; /* u = (double *)malloc((unsigned)(last-first+1) * sizeof(double)); */ u[0] = 0.0; for (i = first+1; i <= last; i++) { u[i-first] = u[i-first-1] + V2DistanceBetween2Points(d[i], d[i-1]); } for (i = first + 1; i <= last; i++) { u[i-first] = u[i-first] / u[last-first]; //--System.out.print(" "+u[i-first]); } //--System.out.println("\nEXITING ChordLengthParametrize"); return(u); } /* * ComputeMaxError : * Find the maximum squared distance of digitized points * to fitted curve. */ public double ComputeMaxError(Vector2 [] d, int first, int last, Vector2 [] bezCurve, double [] u, int [] splitPoint) /* d; Array of digitized points */ /* first, last; Indices defining region */ /* BezierCurve bezCurve Fitted Bezier curve */ /* u; Parameterization of points */ /* splitPoint; Point of maximum error */ { int i; double maxDist; /* Maximum error */ double dist; /* Current error */ Vector2 P; /* Point on curve */ Vector2 v; /* Vector from point to curve */ //System.out.println("ENTERING MAX ERROR"+splitPoint[0]); splitPoint[0] = (last - first + 1)/2; /* *splitPoint = (last - first + 1)/2; */ maxDist = 0.0; for (i = first + 1; i < last; i++) { P = BezierII(3, bezCurve, u[i-first]); v = V2SubII(P, d[i]); dist = v.V2SquaredLength(); /* dist = V2SquaredLength(&v); */ if (dist >= maxDist) { maxDist = dist; /* *splitPoint = i; */ splitPoint[0] = i; } } //System.out.println("EXITING MAX ERROR"+splitPoint[0]); //--System.out.println("splitPoint "+splitPoint[0]+" and maxDist "+maxDist); return (maxDist); } /* * Reparameterize: * Given set of points and their parameterization, try to find * a better parameterization. * */ public double [] Reparameterize(Vector2 [] d, int first, int last, double [] u, Vector2 [] bezCurve) /* d; Array of digitized points */ /* first, last; Indices defining region */ /* u; Current parameter values */ /* bezCurve; Current fitted curve */ { int nPts = last-first+1; int i; double [] uPrime = new double [nPts]; /* New parameter values */ /* uPrime = (double *)malloc(nPts * sizeof(double)); */ for (i = first; i <= last; i++) { uPrime[i-first] = NewtonRaphsonRootFind(bezCurve, d[i], u[i-first]); //-- System.out.print(" "+uPrime[i-first]); } //-- System.out.println(); return (uPrime); } /* * NewtonRaphsonRootFind : * Use Newton-Raphson iteration to find better root. */ public double NewtonRaphsonRootFind(Vector2 [] Q, Vector2 P, double u) /* Q; Current fitted curve */ /* P; Digitized point */ /* u; Parameter value for "P" */ { double numerator, denominator; Vector2 [] Q1 = new Vector2[3]; Vector2 [] Q2= new Vector2[2]; /* Q' and Q'' */ Vector2 Q_u, Q1_u, Q2_u; /*u evaluated at Q, Q', & Q'' */ double uPrime; /* Improved u */ int i; /* Compute Q(u) */ Q_u = BezierII(3, Q, u); /* Generate control vertices for Q' */ for (i = 0; i <= 2; i++) { double x1 = Q[i+1].xval() - Q[i].xval(); double y1 = Q[i+1].yval() - Q[i].yval(); Q1[i] = new Vector2(); Q1[i].xset (x1 * 3.0); Q1[i].yset (y1 * 3.0); } /* Generate control vertices for Q'' */ for (i = 0; i <= 1; i++) { double x1 = Q[i+1].xval() - Q[i].xval(); double y1 = Q[i+1].yval() - Q[i].yval(); Q2[i] = new Vector2(); Q2[i].xset ( x1 * 2.0); Q2[i].yset ( y1 * 2.0); } /* Compute Q'(u) and Q''(u) */ Q1_u = BezierII(2, Q1, u); Q2_u = BezierII(1, Q2, u); /* Compute f(u)/f'(u) */ numerator = (Q_u.xval() - P.xval()) * (Q1_u.xval()) + (Q_u.yval() - P.yval()) * (Q1_u.yval()); denominator = (Q1_u.xval()) * (Q1_u.xval()) + (Q1_u.yval()) * (Q1_u.yval()) + (Q_u.xval() - P.xval()) * (Q2_u.xval()) + (Q_u.yval() - P.yval()) * (Q2_u.yval()); /* u = u - f(u)/f'(u) */ uPrime = u - (numerator/denominator); return (uPrime); } /* * FitCurve : * Fit a Bezier curve to a set of digitized points */ //void FitCurve(Vector2 []d, int nPts, double error, PrintStream ps, int i1, int j1) void FitCurve(Vector2 []d, int nPts, double error, PrintWriter pw) /* *d; Array of digitized points */ /* nPts; Number of digitized points */ /* error; User-defined error squared */ /* FILE *fp; */ { Vector2 tHat1, tHat2; /* Unit tangent vectors at endpoints */ int ii, jj; //-- System.out.println("FITTING A CURVE!!!\n\n\n\n"); //-- for (ii=0;ii= MaxCtrlPts) { NslOutOfBoundsBezier ap = new NslOutOfBoundsBezier(); return; } if ((curve[n].xval() == end.xval()) && (curve[n].yval() == end.yval()) ) { System.out.println("CtrlPt["+n+"] = ("+curve[n].xval()+","+curve[n].yval()); pw.println(curve[n].xval()+" "+curve[n].yval() ); // if (ControlPoints[ indexControlPoints ] == 0) ControlPoints[ indexControlPoints ] = new Vector2(); ControlPoints[ indexControlPoints ].xset ( curve[i].xval() ); ControlPoints[ indexControlPoints ].yset ( curve[i].yval() ); /* */ } //System.out.println("\n\n\n\n\n\n\n"); System.out.println("INDEX IS "+ indexControlPoints); /* for (i=0;i < indexControlPoints; i++) System.out.println("CtrlPt["+i+"] = ("+ControlPoints[i].xval()+","+ControlPoints[i].yval()); */ } /* * fitting_main: * Example of how to use the curve-fitting code. Given an array * of points and a tolerance (squared error between points and * fitted curve), the algorithm will generate a piecewise * cubic Bezier representation that approximates the points. * When a cubic is generated, the routine "DrawBezierCurve" * is called, which outputs the Bezier curve just created * (arguments are the degree and the control points, respectively). * */ public int times(int ti) { int num = -1; for (int ii=0;ii< ti; ii++) num = -1* num; return(num); } public void fitting_main(int drawing_time) { //Vector2 d[][] = new Vector2 [x_dimension][y_dimension]; //Vector2 [] d = new Vector2 [drawing_time]; Vector2 d[] = new Vector2 [ MaxCtrlPts ]; end = new Vector2(); for (int kk=0;kk< MaxCtrlPts ;kk++){ d[kk]= new Vector2(); d[kk].xset( times(kk) * kk ); //d[kk].xset( kk ); //d[kk].xset( Math.sin(3*((double)kk) * 3.14156/180.0) ); d[kk].yset( MaxCtrlPts * Math.cos(((double)kk) * 3.14156/180.0) ); System.out.println(" X "+ d[kk].xval() +" Y "+d[kk].yval()); if (kk==( MaxCtrlPts -1)) { end.xset( d[kk].xval() ); end.yset( d[kk].yval() ); System.out.println(" END "+ end.xval() +" "+end.yval()); } } /* d[0] = new Vector2(); d[0].xset(0.0); d[0].yset(0.0); d[1] = new Vector2(); //d[1].xset(0.0); d[1].yset(0.5); d[1].xset(0.0); d[1].yset(1.0); d[2] = new Vector2(); //d[2].xset(1.1); d[2].yset(1.4); d[2].xset(0.); d[2].yset(2.); d[3] = new Vector2(); //d[3].xset(2.1); d[3].yset(1.6); d[3].xset(0.); d[3].yset(3.); d[4] = new Vector2(); //d[4].xset(3.2); d[4].yset(1.1); d[4].xset(0.); d[4].yset(4.); d[5] = new Vector2(); //d[5].xset(3.3); d[5].yset(1.07); d[5].xset(0.); d[5].yset(5.); d[6] = new Vector2(); //d[6].xset(3.6); d[6].yset(0.07); d[6].xset(73.4); d[6].yset(-6.0); d[7] = new Vector2(); //d[7].xset(0.8); d[7].yset(0.29); d[7].xset(0.); d[7].yset(7.); d[8] = new Vector2(); //d[8].xset(3.85); d[8].yset(0.59); d[8].xset(0.); d[8].yset(8.); d[9] = new Vector2(); //d[9].xset(4.0); d[9].yset(0.2); d[9].xset(0.0); d[9].yset(9.); d[10] = new Vector2(); //d[10].xset(4.0); d[10].yset(0.0); d[10].xset(0.0); d[10].yset(10.0); */ /* static Vector2 d[11] = { { 0.0, 0.0 }, { 0.0, 0.5 }, { 1.1, 1.4 }, { 2.1, 1.6 }, { 3.2, 1.1 }, { 3.3, 1.07 }, { 3.6, 0.07 }, { 3.8, 0.29 }, { 3.85, 0.59 }, { 4.0, 0.2 }, { 4.0, 0.0 }, }; */ ControlPoints = new Vector2 [ MaxCtrlPts ]; indexControlPoints = 0; try { PrintWriter pw = new PrintWriter ( new FileOutputStream("debug.log"), true ); double error = 0.1; /* Squared error */ /* FILE *fp; */ int pts, i, j,k ; float x,y,z; pts= MaxCtrlPts ; System.out.print("Fitting curves at time "+drawing_time+"\n\n\n"); FitCurve(d, pts, error, pw); /* Fit the Bezier curves */ //fclose(fp); } catch(IOException e) { } } private float y_max=100, y_min=0; private int data_x_size, data_y_size, x_dimension, y_dimension; private int last_data_pos, draw_time; private float [][][] data; private float []xdata; private float []ydata; private float [][][] tempox; private float [][][] tempoy; private Color boxColor=Color.black; private int VCount; private Vector2 end; public static int dummyv; public static float []xy; public static Vector Xvariable, Yvariable; public static NslFrame frame; public static String xname; public static String yname; public Vector2 [] ControlPoints; public int indexControlPoints; public int MaxCtrlPts = 150 ; // for testing purposes }