<repo_name>BHerpolsheimer/MobileSensorNetwork<file_sep>/Algorithms.java
// <NAME>
// February 2, 2018
// CS 455
// Algorithm implemetations for the movement of the mobile sensor network.

import java.io.*;

public class Algorithms {
  // Computes the euclidean distance between two sensors.
  public static double computeEuclidean(Sensor s1, Sensor s2) {
    return Math.sqrt((s1.getXPosition() - s2.getXPosition()) * 
                     (s1.getXPosition() - s2.getXPosition()) + 
                     (s1.getYPosition() - s2.getYPosition()) * 
                     (s1.getYPosition() - s2.getYPosition())); 
  }

  // Computes the sigma norm of the position of two sensors.
  public static double computeSigmaNorm(Sensor s1, Sensor s2) {
    return (1/Parameters.epsilon) * (Math.sqrt(1 + (Parameters.epsilon * computeEuclidean(s1, s2) * computeEuclidean(s1, s2))) - 1);
  }

  // Computes the sigma norm of a given distance.
  public static double computeSigmaNorm(double input) {
    return (1/Parameters.epsilon) * (Math.sqrt(1 + (Parameters.epsilon * input * input)) - 1);
  }

  // Computes the bump function with respect to a given number.
  public static double computeBump(double input) {
    double h = 0.2;
    if(input >= 0 && input < h)
      return 1;
    else if(input >= h && input <= 1)
      return (0.5) * (1 + Math.cos(Math.PI * (input - h) / (1 - h)));
    else
      return 0;
  }

  // Computes the acceleration of a given sensor using algorithm three.
  public static double[] computeAlgThree(int i, Sensor[] sensorNetwork, Sensor[][] betaNetwork, AdjacencyMatrix adjMatrix, AdjacencyMatrix betaMatrix, Sensor target) {
  	double[] result = computeAlgTwo(i, sensorNetwork, adjMatrix, target);
  	double sum1x = 0, sum1y = 0;
  	double sum2x = 0, sum2y = 0;
    for(int j = 0; j < betaNetwork[i].length; j++)
      if(betaMatrix.getValue(i, j) > 0) {
        sum1x += computePhiAlpha(computeSigmaNorm(sensorNetwork[i], betaNetwork[i][j])) * 
                 computeNijX(sensorNetwork[i], betaNetwork[i][j]);
        sum1y += computePhiAlpha(computeSigmaNorm(sensorNetwork[i], betaNetwork[i][j])) * 
                 computeNijY(sensorNetwork[i], betaNetwork[i][j]);
        sum2x += betaMatrix.getValue(i, j) * (betaNetwork[i][j].getXVelocity() - sensorNetwork[i].getXVelocity());
        sum2y += betaMatrix.getValue(i, j) * (betaNetwork[i][j].getYVelocity() - sensorNetwork[i].getYVelocity());
      }
    result[0] += 120 * sum1x +  2 * Math.sqrt(75) * sum2x;
    result[1] += 120 * sum1y +  2 * Math.sqrt(75) * sum2y;
  	return result;
  }

  // Computes the acceleration of a given sensor using algorithm two.
  public static double[] computeAlgTwo(int i, Sensor[] sensorNetwork, AdjacencyMatrix adjMatrix, Sensor target) {
  	double[] result = computeAlgOne(i, sensorNetwork, adjMatrix);
  	result[0] -= (Parameters.c1mt * (sensorNetwork[i].getXPosition() - target.getXPosition()) +
  		            Parameters.c2mt * (sensorNetwork[i].getXVelocity() - target.getXVelocity()));
    result[1] -= (Parameters.c1mt * (sensorNetwork[i].getYPosition() - target.getYPosition()) +
  		            Parameters.c2mt * (sensorNetwork[i].getYVelocity() - target.getYVelocity()));
  	return result;
  }

  // Computes the acceleration of a given sensor using algorithm one.
  public static double[] computeAlgOne(int i, Sensor[] sensorNetwork, AdjacencyMatrix adjMatrix) {
  	double sum1x = 0, sum1y = 0;
  	double sum2x = 0, sum2y = 0;
    for(int j = 0; j < sensorNetwork.length; j++)
      if(adjMatrix.getValue(i, j) > 0) {
        sum1x += computePhiAlpha(computeSigmaNorm(sensorNetwork[i], sensorNetwork[j])) * 
                 computeNijX(sensorNetwork[i], sensorNetwork[j]);
        sum1y += computePhiAlpha(computeSigmaNorm(sensorNetwork[i], sensorNetwork[j])) * 
                 computeNijY(sensorNetwork[i], sensorNetwork[j]);
        sum2x += adjMatrix.getValue(i, j) * (sensorNetwork[j].getXVelocity() - sensorNetwork[i].getXVelocity());
        sum2y += adjMatrix.getValue(i, j) * (sensorNetwork[j].getYVelocity() - sensorNetwork[i].getYVelocity());
      }

    double[] result = {Parameters.c1a * sum1x + Parameters.c2a * sum2x,
                       Parameters.c1a * sum1y + Parameters.c2a * sum2y};
    return result;
  }

  // Computes nijx for use in the algorithms above.
  public static double computeNijX(Sensor s1, Sensor s2) {
    return (s2.getXPosition() - s1.getXPosition()) / 
           Math.sqrt(1 + Parameters.epsilon * computeEuclidean(s1, s2) * computeEuclidean(s1, s2));
  }

  //Computes nijy for use in the algorithms above.
  public static double computeNijY(Sensor s1, Sensor s2) {
    return (s2.getYPosition() - s1.getYPosition()) / 
           Math.sqrt(1 + Parameters.epsilon * computeEuclidean(s1, s2) * computeEuclidean(s1, s2));
  }

  // Computees PhiAlpha for use in the algorithms above.
  public static double computePhiAlpha(double input) {
    return computeBump(input / computeSigmaNorm(Parameters.interactionRange)) *
    	     computePhi(input - computeSigmaNorm(Parameters.desiredDistance));
  }

  // Computes Phi for use in the algorithms above.
  public static double computePhi(double input) {
    return (0.5) * ((Parameters.a + Parameters.b) * 
    	     computeSigmaOne(input + Parameters.c) + (Parameters.a - Parameters.b));
  }

  // Computes SigmaOne for use in the algorithms above.
  public static double computeSigmaOne(double input) {
  	return input / Math.sqrt(1 + input * input);
  }

  // Computes connectivity.
  public static double computeConnectivity(AdjacencyMatrix adjMatrix) {
  	return (1.0 / Parameters.sensorNumber) * computeRank(adjMatrix);
  }

  // Computes the rank of the given adjacency matrix.
  public static int computeRank(AdjacencyMatrix adjMatrix) {
    int rank = Parameters.sensorNumber;
     
    for (int i = 0; i < rank; i++) {
      if (adjMatrix.getValue(i, i) != 0) {
        for (int j = 0; j < Parameters.sensorNumber; j++) {
          if (j != i) {
            double mult = adjMatrix.getValue(j, i) / adjMatrix.getValue(i, i);
                           
            for (int k = 0; k < rank; k++)
              adjMatrix.setValue(j, k, adjMatrix.getValue(j, k) - mult * adjMatrix.getValue(i, k));
          }
        }
      }
      else
      {
        boolean reduce = true;

        for (int j = i + 1; j < Parameters.sensorNumber; j++) {
          if (adjMatrix.getValue(j, i) != 0) {
            swap(adjMatrix, i, j, rank);
            reduce = false;
            break ;
          }
        }

        if (reduce)
        {
          rank--;

          for (int j = 0; j < Parameters.sensorNumber; j++)
            adjMatrix.setValue(j, i, adjMatrix.getValue(j, rank));
        }
        i--;
      }
    }
         
    return rank;
  }

  // Swaps two values in a given matrix.
  public static void swap(AdjacencyMatrix adjMatrix, int row1, int row2, int col) {
    for (int i = 0; i < col; i++)
    {
      double temp = adjMatrix.getValue(row1, i);
      adjMatrix.setValue(row1, i, adjMatrix.getValue(row2, i));
      adjMatrix.setValue(row2, i, temp);
    }
  }

  // Computes the x value of the center of mass.
  public static double computeXCoM(Sensor[] sensorNetwork) {
    double sum = 0;
    for(int i = 0; i < sensorNetwork.length; i++)
    	sum += sensorNetwork[i].getXPosition();
    return sum / sensorNetwork.length;
  }

  // Computes the y values of the center of mass.
  public static double computeYCoM(Sensor[] sensorNetwork) {
    double sum = 0;
    for(int i = 0; i < sensorNetwork.length; i++)
    	sum += sensorNetwork[i].getYPosition();
    return sum / sensorNetwork.length;
  }

  // Computes Mu for use in obstacle avoidance.
  public static double computeMu(Sensor s1, RoundObstacle o1) {
  	return o1.getRadius() / computeEuclidean(s1, new Sensor(o1.getXPosition(), o1.getYPosition(), 0, 0));
  }

  // Computer Rho for use in obstacle avoidance.
  public static double computeRho(Sensor s1, RoundObstacle o1) {
  	double akx = (s1.getXPosition() - o1.getXPosition()) / computeEuclidean(s1, new Sensor(o1.getXPosition(), o1.getYPosition(), 0, 0));
  	double aky = (s1.getXPosition() - o1.getXPosition()) / computeEuclidean(s1, new Sensor(o1.getXPosition(), o1.getYPosition(), 0, 0));
  	return 1 - (akx * akx + aky * aky);
  }
}<file_sep>/Parameters.java
// <NAME>
// February 2, 2018
// CS 455
// Class to store the parameters for the simulations.

public class Parameters { 
  public static int sensorNumber = 100;
  public static int dimensions = 2;
  public static double desiredDistance = 15;
  public static double scalingFactor = 1.2;
  public static double interactionRange = desiredDistance * scalingFactor;
  public static double epsilon = 0.1;
  public static double delta_t = 0.009;

  public static double c1a = 30;
  public static double c2a = 2 * Math.sqrt(c1a);
  public static double a = 5;
  public static double b = 5;
  public static double c = Math.abs(a - b) / Math.sqrt(4 * a * b);

  public static double c1mt = 1.1;
  public static double c2mt  = 2 * Math.sqrt(c1mt);

  public static int iterations = 900;
}<file_sep>/Display.java
// <NAME>
// February 2, 2018
// CS 455
// Functions to create the objects that will be displayed on screen.

import java.io.*;
import java.util.*;
import java.awt.Color;

public class Display {
  private int xScaleMax;
  private int xscakeMin = 0;
  private int yScaleMax;
  private int yScaleMin = 0;
  private double widthRatio = 0.8;
  private double heightRatio = 0.8;


  // Default constructor for the display object.
  public Display() {
    StdDraw.setCanvasSize(1920, 1000);
    StdDraw.setXscale(0, 1920);
    StdDraw.setYscale(0, 1000);
    xScaleMax = 1920;
    yScaleMax = 1000;
  }

  // Parameterized constructor for the display object.
  public Display(int height, int width) {
    StdDraw.setCanvasSize(width, height);
    StdDraw.setXscale(0, width);
    StdDraw.setYscale(0, height);
    xScaleMax = width;
    yScaleMax = height;
  }

  // Creates a grid using the given parameters for the sector, min max values, intervals, etc.
  public void createGrid(Sector targetSector, double xInterval, double yInterval, 
  	                double[] gridMinMax,
  	                String title, String xLabel, String yLabel) {
    double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	double originX = targetSector.getX() + 0.5 * targetSector.getWidth();
  	double originY = targetSector.getY() + 0.5 * targetSector.getHeight();

    StdDraw.setPenColor(StdDraw.BLACK);
    StdDraw.rectangle(originX, originY, widthRatio/2 * targetSector.getWidth(), 
    	                heightRatio/2 * targetSector.getHeight());

    double intervalCount = ((xMax - xMax % xInterval)  - 
                            (xMin - xMin % xInterval)) / xInterval;
    for (int i = 0; i <= intervalCount; ++i) {
    	double markX = ((widthRatio * targetSector.getWidth()) * 
    		              (1 - (xMax % xInterval - xMin % xInterval) / (xMax - xMin))) * 
    	                ((i / intervalCount) - 0.5) + originX - (widthRatio * targetSector.getWidth()) * 
    	                (xMax % xInterval + xMin % xInterval) / (2 * (xMax - xMin));

      StdDraw.line(markX, originY - (heightRatio * targetSector.getHeight()) * (.50),
       	           markX, originY - (heightRatio * targetSector.getHeight()) * (.48));
      StdDraw.line(markX, originY + (heightRatio * targetSector.getHeight()) * (.50),
       	           markX, originY + (heightRatio * targetSector.getHeight()) * (.48));
      StdDraw.text(markX, originY - (heightRatio * targetSector.getHeight()) * (.50) - 25, 
      	           Double.toString(Math.round((i * xInterval + xMin - xMin % xInterval) * 10) / 10.0), 45);
    }

    intervalCount = ((yMax - yMax % yInterval)  - 
                     (yMin - yMin % yInterval)) / yInterval;
    for (int i = 0; i <= intervalCount; ++i) {
    	double markY = ((heightRatio * targetSector.getHeight()) * 
    		              (1 - (yMax % yInterval - yMin % yInterval) / (yMax - yMin))) * 
    	                ((i / intervalCount) - 0.5) + originY - (heightRatio * targetSector.getHeight()) * 
    	                (yMax % yInterval + yMin % yInterval) / (2 * (yMax - yMin));

      StdDraw.line(originX - (widthRatio * targetSector.getWidth()) * (.50), markY, 
       	           originX - (widthRatio * targetSector.getWidth()) * (.48), markY);
      StdDraw.line(originX + (widthRatio * targetSector.getWidth()) * (.50), markY,
       	           originX + (widthRatio * targetSector.getWidth()) * (.48), markY);
      StdDraw.text(originX - (widthRatio * targetSector.getWidth()) * (.50) - 30, markY, 
      	           Double.toString(Math.round((i * yInterval + yMin - yMin % yInterval) * 10) / 10.0));
    }
  }

  // Creates the given sensor network within the given sector.
  public void createSensorNetwork(Sector targetSector, Sensor[] sensorNetwork,
  	                              double[] gridMinMax) {
  	StdDraw.setPenColor(StdDraw.MAGENTA);
  	for (int i = 0; i < sensorNetwork.length; i++)
      createSensor(targetSector, sensorNetwork[i], gridMinMax);
  }

  // Creates the given beta network within the given sector.
  public void createBetaNetwork(Sector targetSector, Sensor[][] betaNetwork,
  	                              double[] gridMinMax) {
  	StdDraw.setPenColor(StdDraw.BLUE);
  	for(int i = 0; i < betaNetwork.length; i++)
  		for(int j = 0; j < betaNetwork[i].length; j++)
        createSensor(targetSector, betaNetwork[i][j], gridMinMax);
  }

  // Creates the specific sensor given within the given sector.
  public void createSensor(Sector targetSector, Sensor s1, double[] gridMinMax) {
  	double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	double velocityMagnitude = Math.sqrt(s1.getXVelocity() * s1.getXVelocity() + 
  		                                   s1.getYVelocity() * s1.getYVelocity());
  	double xUnit = (velocityMagnitude == 0) ? 1 : s1.getXVelocity() / velocityMagnitude;
  	double yUnit = (velocityMagnitude == 0) ? 0 : s1.getYVelocity() / velocityMagnitude;
    double area = (xMax - xMin) * (yMax - yMin);
    double triLength = 0.01 * Math.sqrt(targetSector.getHeight() * targetSector.getHeight() + targetSector.getWidth() * targetSector.getWidth());
  	double[] xPoints = {findXinSector(s1.getXPosition(), targetSector, xMax, xMin) + Math.sqrt(Math.cbrt(2500.0 / area)) * ((2 * triLength) * xUnit),
  	                    findXinSector(s1.getXPosition(), targetSector, xMax, xMin) + Math.sqrt(Math.cbrt(2500.0 / area)) * ((triLength) * yUnit - (triLength) * xUnit),
  	                    findXinSector(s1.getXPosition(), targetSector, xMax, xMin) + Math.sqrt(Math.cbrt(2500.0 / area)) * ((-triLength) * yUnit - (triLength) * xUnit)};
  	double[] yPoints = {findYinSector(s1.getYPosition(), targetSector, yMax, yMin) + Math.sqrt(Math.cbrt(2500.0 / area)) * ((2 * triLength) * yUnit),
  	                    findYinSector(s1.getYPosition(), targetSector, yMax, yMin) + Math.sqrt(Math.cbrt(2500.0 / area)) * ((-triLength) * xUnit - (triLength) * yUnit),
  	                    findYinSector(s1.getYPosition(), targetSector, yMax, yMin) + Math.sqrt(Math.cbrt(2500.0 / area)) * ((triLength) * xUnit - (triLength) * yUnit)};
  	StdDraw.filledPolygon(xPoints, yPoints);
  }

  // Creates the connections among the sensors within the network.
  public void createConnections(Sector targetSector, Sensor[] sensorNetwork, AdjacencyMatrix adjMatrix,
  	                            double[] gridMinMax) {
  	double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	StdDraw.setPenColor(StdDraw.BLUE);
  	for(int i = 0; i < Parameters.sensorNumber; i++)
  		for(int j = 0; j < i; j++)
  			if(adjMatrix.getValue(i,j) > 0)
  				StdDraw.line(findXinSector(sensorNetwork[i].getXPosition(), targetSector, xMax, xMin), 
  					           findYinSector(sensorNetwork[i].getYPosition(), targetSector, yMax, yMin),
  			             	 findXinSector(sensorNetwork[j].getXPosition(), targetSector, xMax, xMin), 
  			             	 findYinSector(sensorNetwork[j].getYPosition(), targetSector, yMax, yMin));
  }

  // Creates trails behind the sensors as they move.
  public void createTrails(Sector targetSector, List<Double> xPoints, List<Double> yPoints, double[] gridMinMax, Color color) {
  	double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	StdDraw.setPenColor(color);
  	for(int i = 0; i < xPoints.size(); i++)
      StdDraw.point(findXinSector(xPoints.get(i), targetSector, xMax, xMin), findYinSector(yPoints.get(i), targetSector, yMax, yMin));
  }

  // Creates only the most recently updates portions of the trails.
  public void createTrailEnds(Sector targetSector, List<Double> xPoints, List<Double> yPoints, double[] gridMinMax) {
  	double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	StdDraw.setPenColor(StdDraw.DARK_GRAY);
  	for(int i = xPoints.size() - Parameters.sensorNumber; i < xPoints.size(); i++)
      StdDraw.point(findXinSector(xPoints.get(i), targetSector, xMax, xMin), findYinSector(yPoints.get(i), targetSector, yMax, yMin));
  }

  // Plots the valocities of the sensors in a spectrum of colors, one for each sensor node.
  public void plotVelocity(Sector targetSector, Sensor[] sensorNetwork, int iteration, double[] prevVelocity, double[] gridMinMax) {
    double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
    double red, green, blue, frequency = 0.05;
    for(int i = 0; i < sensorNetwork.length; i++) {
    	red = Math.sin(frequency * i + 0) * 127 + 128;
      green = Math.sin(frequency * i + 2 * Math.PI / 3) * 127 + 128;
      blue = Math.sin(frequency * i + 4 * Math.PI / 3) * 127 + 128;
      StdDraw.setPenColor((int) red, (int) green, (int) blue);
      double velocityMagnitude = Math.sqrt(sensorNetwork[i].getXVelocity() * sensorNetwork[i].getXVelocity() + 
  		                                     sensorNetwork[i].getYVelocity() * sensorNetwork[i].getYVelocity());
      StdDraw.line(findXinSector(iteration - 1, targetSector, xMax, xMin), 
      	           findYinSector(prevVelocity[i], targetSector, yMax, yMin),
      	           findXinSector(iteration, targetSector, xMax, xMin), 
      	           findYinSector(velocityMagnitude, targetSector, yMax, yMin));
      prevVelocity[i] = velocityMagnitude;
    }
  }

  // Plots the connectivity of the mobile sensor network.
  public void plotConnectivity(Sector targetSector, AdjacencyMatrix adjMatrix, double[] prevConnectivity, int iteration, double[] gridMinMax) {
    double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
    double newConnectivity = Algorithms.computeConnectivity(adjMatrix);
    StdDraw.setPenColor(StdDraw.BLUE);
    StdDraw.line(findXinSector(iteration - 1, targetSector, xMax, xMin), 
    	            findYinSector(prevConnectivity[0], targetSector, yMax, yMin),
    	            findXinSector(iteration, targetSector, xMax, xMin), 
    	            findYinSector(newConnectivity, targetSector, yMax, yMin));
    prevConnectivity[0] = newConnectivity;
  }

  // Creates the target that the sensors are tracking.
  public void createTarget(Sector targetSector, Sensor target, double[] gridMinMax) {
  	double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	StdDraw.setPenColor(StdDraw.RED);
  	double area = (xMax - xMin) * (yMax - yMin);
    double circleRadius = 0.01 * Math.sqrt(targetSector.getHeight() * targetSector.getHeight() + targetSector.getWidth() * targetSector.getWidth());
  	StdDraw.filledCircle(findXinSector(target.getXPosition(), targetSector, xMax, xMin), 
  		                   findYinSector(target.getYPosition(), targetSector, yMax, yMin),
  		                   Math.sqrt(Math.cbrt(2500.0 / area)) * circleRadius);
  	StdDraw.filledRectangle(findXinSector(target.getXPosition(), targetSector, xMax, xMin), 
	                          findYinSector(target.getYPosition(), targetSector, yMax, yMin),
	                          Math.sqrt(Math.cbrt(2500.0 / area)) * circleRadius * 0.25,
	                          Math.sqrt(Math.cbrt(2500.0 / area)) * circleRadius * 1.5);
  	StdDraw.filledRectangle(findXinSector(target.getXPosition(), targetSector, xMax, xMin), 
	                          findYinSector(target.getYPosition(), targetSector, yMax, yMin),
	                          Math.sqrt(Math.cbrt(2500.0 / area)) * circleRadius * 1.5,
	                          Math.sqrt(Math.cbrt(2500.0 / area)) * circleRadius * 0.25);
  	StdDraw.setPenColor(StdDraw.WHITE);
  	StdDraw.filledCircle(findXinSector(target.getXPosition(), targetSector, xMax, xMin), 
  		                   findYinSector(target.getYPosition(), targetSector, yMax, yMin),
  		                   Math.sqrt(Math.cbrt(2500.0 / area)) * circleRadius * 0.5);
  }

  // Creates a round obstacle for the sensors to avoid.
  public void createRoundObstacle(Sector targetSector, RoundObstacle object, double[] gridMinMax) {
  	double xMin = gridMinMax[0], xMax = gridMinMax[1], yMin = gridMinMax[2], yMax = gridMinMax[3];
  	double area = (xMax - xMin) * (yMax - yMin);
  	StdDraw.setPenColor(StdDraw.GREEN);
  	StdDraw.filledEllipse(findXinSector(object.getXPosition(), targetSector, xMax, xMin), 
  		                    findYinSector(object.getYPosition(), targetSector, yMax, yMin),
  		                    object.getRadius() * targetSector.getWidth() * widthRatio / (xMax - xMin),
  		                    object.getRadius() * targetSector.getHeight() * heightRatio / (yMax - yMin));
  	StdDraw.setPenColor(StdDraw.BLACK);
  	StdDraw.ellipse(findXinSector(object.getXPosition(), targetSector, xMax, xMin), 
  		              findYinSector(object.getYPosition(), targetSector, yMax, yMin),
  		              object.getRadius() * targetSector.getWidth() * widthRatio / (xMax - xMin),
  		              object.getRadius() * targetSector.getHeight() * heightRatio / (yMax - yMin));
  }

  // Clears the given sector of all objects displayed.
  public void clearSector(Sector targetSector) {
  	StdDraw.setPenColor(StdDraw.WHITE);
  	StdDraw.filledRectangle(targetSector.getX() + 0.5 * targetSector.getWidth(), 
  		                      targetSector.getY() + (0.5) * targetSector.getHeight(), 
  		                      0.5 * targetSector.getWidth(), 0.5 * targetSector.getHeight());
  }

  // Finds the given x position relative to the sector.
  public double findXinSector(double desiredX, Sector targetSector, double xMax, double xMin) {
  	return (((desiredX - xMin) / (xMax - xMin)) * (widthRatio) + (1 - widthRatio) / 2) * targetSector.getWidth() + targetSector.getX();
  }

  // Finds the given y position relative to the sector.
  public double findYinSector(double desiredY, Sector targetSector, double yMax, double yMin) {
  	return (((desiredY - yMin) / (yMax - yMin)) * (heightRatio) + (1 - heightRatio) / 2) * targetSector.getHeight() + targetSector.getY();
  }
}<file_sep>/readme.txt
/// Compile and Run Instructions ///

In order to compile this project, simply enter the following command from the
directory in which the java code files are located:

    javac SensorNetwork.java

The program can then be run using the following command:

    java SensorNetwork

Once the program has started, a window will open for the display, and the only
further input that will be required from the user is to press enter in order to
proceed through the various steps of the simulation.

/// Information Regarding the Code ///

This Program consists of nine classes. Eight of these are of my own making. The
core class is the SensorNetwork class in which the various steps of the 
simulation are implemented and the other classes are utilized. The Sensor,
AdjacencyMatrix, and RoundObstacle classes implement objects that are key to
the simulation. Th objects that are implemented are evident based on the names
of the classes. The Parameters class holds values for parameters that will be
used referred to during the simulation. The algorithms class holds functions
for calculating various algorithms that are used during the simulation. The 
Sector and Display classes are for splitting up the window into parts and 
displaying objects within those parts, respectively. The StdDraw class is the
final class that is used and the only one that is not of my own making. This
is a very commonly used java class that provides one with a basic capability
for creating drawings within their programs.<file_sep>/Sensor.java
// <NAME>
// February 2, 2018
// CS 455
// Class to hold and update the information pertaining to a sensor within the network.

import java.io.*;

public class Sensor {
  private double xPosition;
  private double yPosition;
  private double xVelocity;
  private double yVelocity;

  // Default constructor for Sensor object.
  public Sensor() {
  	setXPosition(-10000);
  	setYPosition(-10000);
  	setXVelocity(0);
  	setYVelocity(0);
  }

  // Parameterized constructor for Sensor object.
  public Sensor(double xP, double yP, double xV, double yV) {
    setXPosition(xP);
    setYPosition(yP);
    setXVelocity(xV);
    setYVelocity(yV);
  }

  // Moves the sensor and updates the position and valocity based on
  // the given acceleration.
  public void move(double[] acceleration, double[] gridMinMax) {
  	setXPosition(getXPosition() + getXVelocity() * Parameters.delta_t + 
  		           acceleration[0] * (Parameters.delta_t * Parameters.delta_t / 2));
  	setXVelocity(getXVelocity() + acceleration[0] * Parameters.delta_t);
  	setYPosition(getYPosition() + getYVelocity() * Parameters.delta_t + 
  		           acceleration[1] * (Parameters.delta_t * Parameters.delta_t / 2));
  	setYVelocity(getYVelocity() + acceleration[1] * Parameters.delta_t);
  	if(getXPosition() < gridMinMax[0])
  		gridMinMax[0] = getXPosition();
  	else if(getXPosition() > gridMinMax[1])
  		gridMinMax[1] = getXPosition();
  	if(getYPosition() < gridMinMax[2])
  		gridMinMax[2] = getYPosition();
  	else if(getYPosition() > gridMinMax[3])
  		gridMinMax[3] = getYPosition();
  }

  // Methods to modify the private class values.
  public void setXPosition(double x) {
    xPosition = x;
  }
  public void setYPosition(double y) {
    yPosition = y;
  }
  public void setXVelocity(double x) {
    xVelocity = x;
  }
  public void setYVelocity(double y) {
    yVelocity = y;
  }

  // Methods to return the private class values.
  public double getXPosition() {
    return xPosition;
  }
  public double getYPosition() {
    return yPosition;
  }
  public double getXVelocity() {
    return xVelocity;
  }
  public double getYVelocity() {
    return yVelocity;
  }
}