The following is the web exercise 3.2.12. from the book *Computer Science An Interdisciplinary Approach* by Sedgewick & Wayne:

Write a program that draws a vector field. A vector field associates a vector with every point in a Euclidean

space. Widely used in physics to model speed and direction of a moving

object or strength and direction of a Newtonian force.

Here is my program:

```
public class Vector {
private final double() coordinates;
public Vector(double() coordinates) {
this.coordinates = coordinates;
}
private int getCoordinatesLength() {
return coordinates.length;
}
public double getCoordinate(int index) {
return coordinates(index - 1);
}
public double getLength() {
double sumOfCoordinatesSquared = 0;
for (int i = 0; i < getCoordinatesLength(); i++) {
sumOfCoordinatesSquared += getCoordinate(i + 1) * getCoordinate(i + 1);
}
return Math.sqrt(sumOfCoordinatesSquared);
}
private double getDirection2D() {
return Math.atan(getCoordinate(2) / getCoordinate(1));
}
public double() getDirection() {
if (getCoordinatesLength() != 2 && getCoordinatesLength() != 3) {
throw new IllegalArgumentException("dimention of the vector must be either 2 or 3");
}
int dimention = 0;
if (getCoordinatesLength() == 2) dimention = 1;
else if (getCoordinatesLength() == 3) dimention = 2;
double() angles = new double(dimention);
if (getCoordinatesLength() == 2) {
angles(0) = Math.atan(getCoordinate(2) / getCoordinate(1));
} else if (getCoordinatesLength() == 3) {
double vectorLength = getLength();
double azimuth = Math.atan(getCoordinate(2) / getCoordinate(1));
double zenith = Math.acos(getCoordinate(3) / vectorLength);
angles(0) = azimuth;
angles(1) = zenith;
}
return angles;
}
public Vector add(Vector otherVector) {
if (getCoordinatesLength() != otherVector.getCoordinatesLength()) {
throw new IllegalArgumentException("length of the vectors must be equal");
}
double() newCoordinates = new double(getCoordinatesLength());
for (int i = 0; i < getCoordinatesLength(); i++) {
newCoordinates(i) = getCoordinate(i + 1) + otherVector.getCoordinate(i + 1);
}
return new Vector(newCoordinates);
}
public Vector multiplyByScalar(double scalar) {
double() newCoordinates = new double(getCoordinatesLength());
for (int i = 0; i < getCoordinatesLength(); i++) {
newCoordinates(i) = getCoordinate(i + 1) * scalar;
}
return new Vector(newCoordinates);
}
public Vector subtract(Vector otherVector) {
return add(otherVector.multiplyByScalar(-1.0));
}
public boolean isEqual(Vector otherVector) {
if (getCoordinatesLength() != otherVector.getCoordinatesLength()) return false;
for (int i = 0; i < getCoordinatesLength(); i++) {
if (getCoordinate(i + 1) != otherVector.getCoordinate(i + 1)) return false;
}
return true;
}
public double applyDotProduct(Vector otherVector) {
if (getCoordinatesLength() != otherVector.getCoordinatesLength()) {
throw new IllegalArgumentException("length of the vectors must be equal");
}
double dotProduct = 0;
for (int i = 0; i < getCoordinatesLength(); i++) {
dotProduct += getCoordinate(i + 1) * otherVector.getCoordinate(i + 1);
}
return dotProduct;
}
public Vector applyCrossProduct(Vector otherVector) {
if (getCoordinatesLength() != otherVector.getCoordinatesLength()) {
throw new IllegalArgumentException("length of the vectors must be equal");
}
if (getCoordinatesLength() != 3) {
throw new IllegalArgumentException("dimention of the vector must be 3");
}
int x = 1;
int y = 2;
int z = 3;
double newXCoordinate = getCoordinate(y) * otherVector.getCoordinate(z) - getCoordinate(z) * otherVector.getCoordinate(y);
double newYCoordinate = getCoordinate(z) * otherVector.getCoordinate(x) - getCoordinate(x) * otherVector.getCoordinate(z);
double newZCoordinate = getCoordinate(x) * otherVector.getCoordinate(y) - getCoordinate(y) * otherVector.getCoordinate(x);
double() newCoordinates = {
newXCoordinate,
newYCoordinate,
newZCoordinate
};
return new Vector(newCoordinates);
}
public boolean isPerpendicular(Vector otherVector) {
if (applyDotProduct(otherVector) == 0) return true;
else return false;
}
public boolean isParallel(Vector otherVector) {
double scalingFactor = 0;
for (int i = 0; i < getCoordinatesLength(); i++) {
if (getCoordinate(i + 1) != 0 && otherVector.getCoordinate(i + 1) != 0) {
scalingFactor = getCoordinate(i + 1) / otherVector.getCoordinate(i + 1);
break;
}
}
double() newCoordinates = new double(getCoordinatesLength());
for (int i = 0; i < getCoordinatesLength(); i++) {
newCoordinates(i) = getCoordinate(i + 1) / scalingFactor;
}
Vector newVector = new Vector(newCoordinates);
if (otherVector.isEqual(newVector)) return true;
else return false;
}
public String toString() {
String printedCoordinates = "";
for (int i = 0; i < getCoordinatesLength() - 1; i++) {
printedCoordinates += (getCoordinate(i + 1) + ", ");
}
return "(" + printedCoordinates + getCoordinate(getCoordinatesLength()) + ")";
}
public void draw(double originX, double originY, double scaleDownFactor, double arrowHeadSize) {
if (getCoordinatesLength() != 2) {
throw new IllegalArgumentException("dimention of the vector must be 3");
}
double newX = getCoordinate(1) * scaleDownFactor;
double newY = getCoordinate(2) * scaleDownFactor;
double arrowHeadPointX = originX + newX;
double arrowHeadPointY = originY + newY;
StdDraw.line(originX, originY, arrowHeadPointX, arrowHeadPointY);
double arrowHeadBaseX = arrowHeadSize * Math.sin(getDirection2D());
double arrowHeadBaseY = arrowHeadSize * Math.cos(getDirection2D());
double() arrowHeadXCoordinates = {-arrowHeadBaseX + (originX + 0.95 * newX),
arrowHeadBaseX + (originX + 0.95 * newX),
arrowHeadPointX
};
double() arrowHeadYCoordinates = {
arrowHeadBaseY + (originY + 0.95 * newY),
-arrowHeadBaseY + (originY + 0.95 * newY),
arrowHeadPointY
};
StdDraw.filledPolygon(arrowHeadXCoordinates, arrowHeadYCoordinates);
}
public static void main(String() args) {
/*
double() coordinatesOfVectorA = {1,2};
double() coordinatesOfVectorB = {0,1};
Vector vectorA = new Vector(coordinatesOfVectorA);
Vector vectorB = new Vector(coordinatesOfVectorB);
double originX = 0.5;
double originY = 0.5;
double scaleDownFactor = 0.1;
double arrowHeadSize = 0.01;
System.out.println("Vector A = " + vectorA.toString());
System.out.println("Vector B = " + vectorB.toString());
System.out.println("A plus B equals " + vectorA.add(vectorB).toString());
System.out.println("A minus B equals " + vectorA.subtract(vectorB).toString());
System.out.println("Dot product of A and B equals " + vectorA.applyDotProduct(vectorB));
//System.out.println("Cross product of A and B equals " + vectorA.applyCrossProduct(vectorB).toString());
System.out.println(vectorA.isParallel(vectorB));
vectorA.draw(originX, originY, scaleDownFactor, arrowHeadSize);
vectorB.draw(originX, originY, scaleDownFactor, arrowHeadSize);
*/
StdDraw.setXscale(-1, 1);
StdDraw.setYscale(-1, 1);
for (int i = -10; i < 11; i++) {
for (int j = -10; j < 11; j++) {
if (i == 0 && j == 0) j++;
double x = 1.0 * i / 10;
double y = 1.0 * j / 10;
double vectorXCoordinate = -y;
double vectorYCoordinate = x;
double() coordinates = {
vectorXCoordinate,
vectorYCoordinate
};
Vector vector = new Vector(coordinates);
vector.draw(x, y, 0.1, 0.01);
}
}
}
}
```

StdDraw is a simple API written by the authors of the book. I checked my program and it works. Here is one instance of it:

Input (taken from here):

Output:

Is there any way that I can improve my program?

Thanks for your attention.