Sunday 25 December 2016

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

15.16 (Two movable vertices and their distances)
Write a program that displays two circles with radius 10 at location
(40, 40) and (120, 150) with a line connect- ing the two circles,
as shown in Figure 15.28b. The distance between the circles is displayed
along the line. The user can drag a circle. When that happens, the circle
and its line are moved and the distance between the circles is updated.

public class MyPoint {

    public double x;
    public double y;

    public MyPoint(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public MyPoint() {
        this(0,0);
    }

    public double x() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double y() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public double distance(double x, double y) {
        return Math.sqrt((this.x - x) * (this.x - x) + (this.y - y) * (this.y - y));
    }

    public double distance(MyPoint point) {

        return distance(point.x, point.y);
    }

    public MyPoint getCenterPoint(MyPoint p) {

        return new MyPoint((p.x + this.x) / 2, (p.y + this.y) / 2);
    }

    public static MyPoint getCenterPoint(double x1, double y1, double x2, double y2) {
        return new MyPoint((x1 + x2) / 2, (y1 + y2) / 2);
    }

    /** Return true if this point is on the left side of the
     *  directed line from p0 to p1 */
    public boolean leftOfTheLine(MyPoint p0, MyPoint p1) {

        return leftOfTheLine(p0.x, p0.y, p1.x, p1.y, x, y);
    }

    /** Return true if this point is on the same
     *  line from p0 to p1 */
    public boolean onTheSameLine(MyPoint p0, MyPoint p1) {

        return onTheSameLine(p0.x, p0.y, p1.x, p1.y, x, y);

    }

    /** Return true if this point is on the right side of the
     *  directed line from p0 to p1 */
    public boolean rightOfTheLine(MyPoint p0, MyPoint p1) {

        return rightOfTheLine(p0.x, p0.y, p1.x, p1.y, x, y);

    }

    /** Return true if this point is on the
     *  line segment from p0 to p1 */
    public boolean onTheLineSegment(MyPoint p0, MyPoint p1) {

        return onTheLineSegment(p0.x, p0.y, p1.x, p1.y, x, y);

    }


    /** Return true if point (x2, y2) is on the left side of the
     *  directed line from (x0, y0) to (x1, y1) */
    public static boolean leftOfTheLine(double x0, double y0, double x1, double y1, double x2, double y2){

        return (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0) > 0;
    }
    /** Return true if point (x2, y2) is on the same
     *  line from (x0, y0) to (x1, y1) */
    public static boolean onTheSameLine(double x0, double y0, double x1, double y1, double x2, double y2) {

        return (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0) == 0;
    }
    /** Return true if point (x2, y2) is on the
     *  line segment from (x0, y0) to (x1, y1) */
    public static boolean onTheLineSegment(double x0, double y0, double x1, double y1, double x2, double y2) {

        double position = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0);

        return position <= 0.0000000001 && ((x0 <= x2 && x2 <= x1) || (x0 >= x2 && x2 >= x1));
    }

    /** Return true if point (x2, y2) is on the right side of the
     *  directed line from (x0, y0) to (x1, y1) */
    public static boolean rightOfTheLine(double x0, double y0, double x1, double y1, double x2, double y2){

        return (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0) < 0;
    }

    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }

}

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_16 extends Application {

    Boolean isFocusedOnC1 = false;
    Boolean isFocusedOnC2 = false;

    @Override
    public void start(Stage primaryStage) throws Exception {

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

        Circle c1 = new Circle(40, 40, radius, Color.TRANSPARENT);
        c1.setStroke(Color.BLACK);
        Text txt1 = new Text(c1.getCenterX(), c1.getCenterY(), "1");
        txt1.xProperty().bind(c1.centerXProperty());
        txt1.yProperty().bind(c1.centerYProperty());

        Circle c2 = new Circle(120, 150, radius, Color.TRANSPARENT);
        c2.setStroke(Color.BLACK);
        Text txt2 = new Text(c2.getCenterX(), c2.getCenterY(), "2");
        txt2.xProperty().bind(c2.centerXProperty());
        txt2.yProperty().bind(c2.centerYProperty());

        Text txtPoint = new Text();
        Line line = new Line();
        updateLine(line, c1, c2, txtPoint);

        c1.setOnMouseDragged(e-> {
            double x = e.getX();
            double y = e.getY();
            c1.setCenterX(x);
            c1.setCenterY(y);
            updateLine(line, c1, c2, txtPoint);

        });

        c2.setOnMouseDragged(e-> {
            double x = e.getX();
            double y = e.getY();
            c2.setCenterX(x);
            c2.setCenterY(y);
            updateLine(line, c1, c2, txtPoint);

        });

        pane.getChildren().addAll(txt1, txt2, c1, c2, line, txtPoint);
        primaryStage.setTitle("Draw Two Circle");
        primaryStage.setScene(new Scene(pane, width, height));
        primaryStage.show();
    }

    /** Connect two circles centered at (x1, y1) and (x2, y2) */
    private void updateLine(Line line, Circle c1, Circle c2, Text txtPoint) {

        double x1 = c1.getCenterX();
        double y1 = c1.getCenterY();
        double x2 = c2.getCenterX();
        double y2 = c2.getCenterY();
        double radius = c1.getRadius();

        double d = Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
        int x11 = (int) (x1 - radius * (x1 - x2) / d);
        int y11 = (int) (y1 - radius * (y1 - y2) / d);
        int x21 = (int) (x2 + radius * (x1 - x2) / d);
        int y21 = (int) (y2 + radius * (y1 - y2) / d);

        line.setStartX(x11);
        line.setStartY(y11);
        line.setEndX(x21);
        line.setEndY(y21);
        txtPoint.setText(String.format("%.2f", PaneCollection.distance(line)));
        MyPoint p = PaneCollection.getCenterPoint(line);
        txtPoint.setX(p.x);
        txtPoint.setY(p.y);
    }

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

No comments :

Post a Comment