/*Siddhartha Kasivajhula * Georgia Institute of Technology * c/o Predrag Cvitanovic * Advisor: Rytis Paskauskas * Fall 2005 */ //! @brief This class represents the surface. /// Currently, there is only one type of surface -- sinusoidal, and any surface object will be sinusoidal, represented completely by this class. In future, we can make this an abstract class, and create child classes called Sinusoidal, Triangular, etc. public class Surface { public static final double L = AFMConstants.SURF_LENGTH; //!< Length of 1 period of the surface static final int SAMPLES = AFMConstants.SAMPLES; //!< Number of samples static final double INTERVAL = L / (SAMPLES - 1); //!< divides surface into samples private double[] x; //!< array of x-values of surface points private double[] y; //!< array of y-values of surface points private double[] dy; //!< array of slope at different points on the surface private double A = AFMConstants.SURF_AMPLITUDE; //!< Surface amplitude private double p = AFMConstants.SURF_PHASE; //!< Surface phase private double tx[]; //!< Normalized tangent vector: x component private double ty[]; //!< Normalized tangent vector: y component private double nx[]; //!< Normalized normal vector: x component private double ny[]; //!< Normalized normal vector: y component //! @brief Constructor. Calculates and stores surface points /// initializes all arrays. surface points, slope values. normal and tangent vectors are all calculated and stored public Surface() // Constructor { // sets up arrays, defines surface function x = new double[SAMPLES]; y = new double[SAMPLES]; dy = new double[SAMPLES]; tx = new double[SAMPLES]; ty = new double[SAMPLES]; nx = new double[SAMPLES]; ny = new double[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 < SAMPLES; i++) // initialises all values: x,y,slope,tangent and normal vectors { 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 //! returns the type of surface as a string. For example, "sin". This method is not currently used public String getType() { return "sin"; } //! returns amplitude public double getA() { return A; } //! returns phase public double getP() { return p; } //! returns length of 1 period of surface public double getL() { return L; } //! returns precise y for a precise x 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))); } //! return x at the given index public double getX(int index) { return x[index]; } //! return y at the given index public double getY(int index) { return y[index]; } //! given an x, return y corresponding to the closest x in the array public double getY(double x) // return y given x. Not precise: { // returns y value at closest index int temp = (int) Math.round(x / L * SAMPLES); do { if (temp >= SAMPLES) temp = temp - SAMPLES; // in case the AFM is beyond if (temp < 0) temp = temp + SAMPLES; // surface array boundaries, y value can still } while (!(temp >= 0 && temp < SAMPLES)); return y[temp]; // be found by "wrapping around" } //! return slope at given index public double getSlope(int index) { return dy[index]; } //! return x-component of normal vector at the given index public double getNX(int index) // x- component of normal vector *at a particular array index* { return nx[index]; } //! return y-component of normal vector at the given index public double getNY(int index) // y-component of normal vector *at a particular array index* { return ny[index]; } //! return x-component of normal vector at any given x (this is precise) 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; } //! return y-component of normal vector at any given x (this is precise) 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; } //! for testing purposes only. public static void main(String[] args) // for testing { Surface sine = new Surface(); System.out.println(sine.gimmeY(-0.01628030494365129)); } }// end Surface