## Sunday, 25 December 2016

### Chapter 15 Exercise 20, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.

15.20 (Geometry: display angles)
Write a program that enables the user to drag the
vertices of a triangle and displays the angles dynamically
as the triangle shape changes, as shown in Figure 15.30a.
The formula to compute angles is given in Listing 4.1.

import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;

import java.util.ArrayList;

public class PaneCollection {

public static void drawArrowLine(double x1, double y1, double x2,   double y2, Pane pane) {
drawArrowLine(x1, y1, x2, y2, pane, 15);
}

public static void drawArrowLine(double x1, double y1, double x2,   double y2, Pane pane, int length) {
drawArrowLine(new Line(x1, y1, x2, y2), pane, length);
}

public static void drawArrowLine(Line line, Pane pane) {
drawArrowLine(line, pane, 15);
}

public static void drawArrowLine(Line line, Pane pane, int length) {
ObservableList<Node> list = pane.getChildren();

double arctan = Math.atan(slope(line));
double set45 = (line.getStartX() > line.getEndX()) ? 1.57 / 2 : -1.57 * 1.5;

(line.getEndX() + Math.cos(arctan - set45) * length),
(line.getEndY() + Math.sin(arctan - set45) * length)));
(line.getEndX() + Math.cos(arctan + set45) * length),
(line.getEndY() + Math.sin(arctan + set45) * length)));
}

public static double slope(Line line) {
return (line.getStartY() - line.getEndY()) / (line.getStartX() - line.getEndX());
}

public static double distance(double x1, double y1, double x2, double y2) {

return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

public static double distance(Line line) {
return distance(line.getStartX(), line.getStartY(), line.getEndX(), line.getEndY());
}

public static MyPoint getCenterPoint(Line line) {

return new MyPoint(
(line.getStartX() + line.getEndX()) / 2,
(line.getStartY() + line.getEndY()) / 2);
}

public static void drawPointCounter(Pane pane, Point2D[] points) {
int counter = 1;

for (Point2D point : points) {
Circle temp = new Circle(point.getX(), point.getY(), 5, Color.TRANSPARENT);
Text text = new Text(point.getX(), point.getY(), "" + counter++);
}
}

public static boolean containsPoint(ArrayList<Point2D> points, double x, double y) {
for (Point2D p : points) {
if (p.getX() == x && p.getY() == y) return true;
}
return false;
}

public static boolean removePoint(ArrayList<Point2D> points, double x, double y) {

int index = 0;
for (Point2D p : points) {
if (p.getX() == x && p.getY() == y) {
points.remove(index);
return true;
}
index++;
}
return false;
}

public static Line copyLine(Line l) {
return new Line(l.getStartX(), l.getStartY(), l.getEndX(), l.getEndY());
}

}


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Exercise_20 extends Application {

Pane pane = new Pane();
double width = 400;
double height = 400;

@Override
public void start(Stage primaryStage) {

Circle[] p = new Circle[3];
Line[] lines = new Line[3];
Text[] texts = new Text[3];
for (int i = 0; i < p.length; i++) {
p[i] = new Circle(0,0,10);
setRandomLocation(p[i]);
texts[i] = new Text();
final int index = i; // for use in lambda expression
p[i].setOnMouseDragged(e-> {
p[index].setCenterX(e.getX());
p[index].setCenterY(e.getY());
updateLines(lines, p, texts);
});

}
for (int i = 0; i < lines.length; i++) {
int cIndex2 = (i + 1 >= p.length) ? 0 : i + 1;
lines[i] = new Line(
p[i].getCenterX(), p[i].getCenterY(),
p[cIndex2].getCenterX(), p[cIndex2].getCenterY());

}
updateLines(lines,p,texts);
primaryStage.setScene(new Scene(pane, width, height));
primaryStage.setTitle("Game: eye-hand coordination");
primaryStage.show();
}

private void updateLines(Line[] lines, Circle[] p, Text[] angles) {
for (int i = 0; i < lines.length; i++) {

int cIndex2 = (i + 1 >= p.length) ? 0 : i + 1;
lines[i].setStartX(p[i].getCenterX());
lines[i].setStartY(p[i].getCenterY());
lines[i].setEndX(p[cIndex2].getCenterX());
lines[i].setEndY(p[cIndex2].getCenterY());
angles[i].setX(p[i].getCenterX() + 5);
angles[i].setY(p[i].getCenterY() - 5);

}

double a = PaneCollection.distance(lines[0]);
double b = PaneCollection.distance(lines[1]);
double c = PaneCollection.distance(lines[2]);

double A = Math.toDegrees(Math.acos((a * a - b * b - c * c) / (-2 * b * c)));
angles[2].setText(String.format("%.2f 1", A));

double B = Math.toDegrees(Math.acos((b * b - a * a - c * c) / (-2 * a * c)));
angles[0].setText(String.format("%.2f 2", B));

double C = Math.toDegrees(Math.acos((c * c - b * b - a * a) / (-2 * a * b)));
angles[1].setText(String.format("%.2f 3", C));

}
private void setRandomLocation(Circle c) {

double min = c.getRadius() + 5;
double max = width - c.getRadius() - 5;
c.setCenterX((Math.random() * (max - min) + min));
max = height - c.getRadius() - 5;
c.setCenterY((Math.random() * (max - min) + min));

}

public static void main(String[] args) {
Application.launch(args);
}

}