Sunday 25 December 2016

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

15.21 (Drag points) Draw a circle with three random points on the circle. Connect
the points to form a triangle. Display the angles in the triangle. Use the mouse
to drag a point along the perimeter of the circle. As you drag it, the triangle and
angles are redisplayed dynamically, as shown in Figure 15.30b. For computing
angles in a triangle, see 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;

        list.add(line);
        list.add(new Line(line.getEndX(), line.getEndY(),
                (line.getEndX() + Math.cos(arctan - set45) * length),
                (line.getEndY() + Math.sin(arctan - set45) * length)));
        list.add(new Line(line.getEndX(), line.getEndY(),
                (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++);
            pane.getChildren().addAll(temp, text);
        }
    }

    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.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Exercise_21 extends Application {
    Pane pane = new Pane();
    double width = 400;
    double height = 400;

    @Override
    public void start(Stage primaryStage) {


        Circle c = new Circle(width / 2, height / 2, 100);
        pane.getChildren().add(c);

        c.setFill(Color.TRANSPARENT);
        c.setStroke(Color.BLACK);
        Circle[] p = new Circle[3];
        Line[] lines = new Line[3];
        Text[] texts = new Text[3];
        for (int i = 0; i < p.length; i++) {

            texts[i] = new Text();
            p[i] = new Circle(0, 0, 5);
            setRandomLocation(p[i], c);

            final int index = i; // for use in lambda expression

            p[i].setOnMouseDragged(e -> {

                double radian = Math.atan2(e.getY() - c.getCenterY(), e.getX() - c.getCenterX());
                double x = c.getCenterX() + c.getRadius() * Math.cos(radian);
                double y = c.getCenterY() + c.getRadius() * Math.sin(radian);
                p[index].setCenterX(x);
                p[index].setCenterY(y);
                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);
        pane.getChildren().addAll(lines);
        pane.getChildren().addAll(texts);
        pane.getChildren().addAll(p);
        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 tPoint, Circle c) {

        double angle = Math.random() * 360;
        double x = c.getCenterX() + c.getRadius() * Math.cos(Math.toRadians(angle));
        double y = c.getCenterY() + c.getRadius() * Math.sin(Math.toRadians(angle));
        tPoint.setCenterX(x);
        tPoint.setCenterY(y);

    }

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

No comments :

Post a Comment