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.
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