/*Siddhartha Kasivajhula * Georgia Institute of Technology * c/o Predrag Cvitanovic * Advisor: Rytis Paskauskas * Fall 2005 */ import java.util.StringTokenizer; //import cs1.Keyboard; public class Surface { public static final double L = 1; // Length of surface ("period") static final double INTERVAL = L / (AFMConstants.SAMPLES - 1); // divide length into 1000 samples private double[] x; // x private double[] y; // y private double[] dy; //here you are, thinking about derivatives // slope private double[] angle; // theta value at any point private double A; // Amplitude private double p; // Phase private double tx[]; // Normalised tangent vector: x component private double ty[]; // Normalised tangent vector: y component private double nx[]; // Normalised normal vector: x component private double ny[]; // Normalised normal vector: y component public Surface() // Constructor { // sets up arrays, defines surface function x = new double[AFMConstants.SAMPLES]; y = new double[AFMConstants.SAMPLES]; dy = new double[AFMConstants.SAMPLES]; tx = new double[AFMConstants.SAMPLES]; ty = new double[AFMConstants.SAMPLES]; nx = new double[AFMConstants.SAMPLES]; ny = new double[AFMConstants.SAMPLES]; A = 0.038533472746501492; // amplitude p = -0.67113170769742891 + 0.5 - 0.25025025025025052494942851164536;//-0.17113170769742891;//0.6385710978101264;//-0.17113170769742891;//0.3288682923025711;//0.13857109781012633;//0.67113170769742891//+0.3288682923025711;//+0.17401688954879357;//-2*0.016280304943651295; // phase for (int i = 0; i < AFMConstants.SAMPLES; i++) // initialises all values: x,y,slope,tangent and normal vectors { //x[i] = -2*Surface.L+4*INTERVAL*i; // this has 4 Ls, so period = 4 ////x[i] = -Surface.L/2+INTERVAL*i; // corrected: Period =L x[i] = INTERVAL * i; y[i] = A * Math.sin(2 * Math.PI / Surface.L * (x[i] - p * Surface.L)); dy[i] = A * 2 * Math.PI / Surface.L * Math.cos(2 * Math.PI / Surface.L * (x[i] - p * Surface.L)); tx[i] = 1 / Math.pow((dy[i] * dy[i] + 1), 0.5); ty[i] = dy[i] * tx[i]; // ty = m*tx nx[i] = -ty[i]; // for normal, simply switch coefficients and negate x coefficient ny[i] = tx[i]; // } }//end constructor public void reset(int index, double V, double[] t) { /* Resets the surface function, slope, and normal vectors */ /* Only used in Lab frame animation. Not used in any other simulation. Ignore*/ for (int i = 0; i < AFMConstants.SAMPLES; i++) { y[i] = A * Math.sin(2 * Math.PI / Surface.L * (x[i] + V * t[index] * Surface.L - p * Surface.L)); dy[i] = A * 2 * Math.PI / Surface.L * Math.cos(2 * Math.PI / Surface.L * (x[i] + V * Surface.L * t[index] - p * Surface.L)); tx[i] = 1 / Math.pow((dy[i] * dy[i] + 1), 0.5); ty[i] = dy[i] * tx[i]; // ty = m*tx nx[i] = -ty[i]; // for normal, simply switch coefficients and negate x coefficient ny[i] = tx[i]; // } }//end reset public double gimmeY(double x) // returns precise y for a precise x { return (A * Math.sin(2 * Math.PI / Surface.L * (x - p * Surface.L))); } public double getX(int index) { return x[index]; } public double getY(int index) { return y[index]; } public double getY(double x) // return y given x. Not precise: { // returns y value at closest index int temp = (int) Math.round((double) x / L * AFMConstants.SAMPLES); //int temp = (int)Math.round((double)(x+2*L)/(4*L)*AFMConstants.SAMPLES); do { if (temp >= AFMConstants.SAMPLES) temp = temp - AFMConstants.SAMPLES; // in case the AFM is beyond if (temp < 0) temp = temp + AFMConstants.SAMPLES; // surface array boundaries, y value can still } while (!(temp >= 0 && temp < AFMConstants.SAMPLES)); return y[temp]; // be found by "wrapping around" } public double getSlope(int index) { return dy[index]; } public double getNX(int index) // x- component of normal vector *at a particular array index* { return nx[index]; } public double getNY(int index) // y-component of normal vector *at a particular array index* { return ny[index]; } public double getNX(double x) // return precise x-component of normal vector for *any* given precise x { double yTemp = A * Math.sin(2 * Math.PI / Surface.L * (x - p * Surface.L)); // equation of the surface double dyTemp = A * 2 * Math.PI / Surface.L * Math.cos(2 * Math.PI / Surface.L * (x - p * Surface.L)); // derivative double txTemp = 1 / Math.pow((dyTemp * dyTemp + 1), 0.5); // tangent x double tyTemp = dyTemp * txTemp; // ty = m*tx double nxTemp = -tyTemp; // for normal, simply switch coefficients and negate x coefficient return nxTemp; } public double getNY(double x) // return precise y-component of normal vector for *any* given precise x { double yTemp = A * Math.sin(2 * Math.PI / Surface.L * (x - p * Surface.L)); double dyTemp = A * 2 * Math.PI / Surface.L * Math.cos(2 * Math.PI / Surface.L * (x - p * Surface.L)); double txTemp = 1 / Math.pow((dyTemp * dyTemp + 1), 0.5); double tyTemp = dyTemp * txTemp; // ty = m*tx double nyTemp = txTemp; // for normal, simply switch coefficients and negate x coefficient return nyTemp; } public double gitY(double p) { double x = -0.016280304943651295; double yTemp = A * Math.sin(2 * Math.PI / Surface.L * (x - p * Surface.L)); return yTemp; } public static void main(String[] args) // for testing { Surface sine = new Surface(); System.out.println(sine.gimmeY(-0.01628030494365129)); /* final double SURF_TOLERANCE = 1.e-17; double x, xo, xn, yo, yn, err, po, pn, p; double y0 = 0.031850050627578848; /* for(p=-1; p<1; p+=0.000001) { if(sine.gitY(p)y0-0.00001) System.out.println("p = " + p + " y = " + sine.gitY(p)); }*/ // between 0.32886899999811914 and 0.32886799999811916 // between 0.1385710000080362 and 0.1385720000080362 //between 325 and 326 //for(int i=324; i<328; i++) //{ //po = 0.32886899999811914; //pn = 0.32886799999811916; /* po = 0.3385710000080362; pn = 0.3385720000080362; yo = sine.gitY( po ) - y0; yn = sine.gitY( pn ) - y0; do { p = -1*(pn*yo-po*yn)/(yn-yo); System.out.println(p); err = sine.gitY(p) - y0; // y(t) - surfaceY(x(t)) maybe some parameters too??? if(err* yn > 0) { yn = err; pn = p; } else { yo = err; po = p; } System.out.println("bisection error = " + err + "\n"); } while(Math.abs(err) > SURF_TOLERANCE); System.out.println(p + "\t" + sine.gitY(p)); /*for(int i=0; i<1000; i++) {// 0.03185235206421146 if(sine.getY(i)<-0.031850050627578848+0.0001 && sine.getY(i)>-0.031850050627578848-0.0001) { System.out.println(i + "\t" + sine.getX(i) + "\t" + sine.gimmeY(sine.getX(i-1))); } } System.out.println(sine.gimmeY(-0.174)); */ ///double x; ///for(int i=0;i<=20;i++){ /// x = (double)(i-10)/20.0; /// System.out.println(x + "\t" + sine.gimmeY(x) ); ///} //System.out.println(sine.gimmeY( 0.016280304943651295)); // System.out.println(sine.getY(5*-0.016280305)); // System.out.println(sine.gimmeY(5*-0.016280305) + " " + sine.gimmeY(-0.0162803063) ); // System.out.println(sine.getY(sine.getX(200)) + " " + sine.getY(sine.getX(200)+2*L)); /*for(x=-Surface.L/2; x