Skip to content

Commit 05a7945

Browse files
authored
Merge pull request #78 from HarryDulaney/chapter-15-solutions
add 24 and 25
2 parents 8db4552 + fc175bc commit 05a7945

2 files changed

Lines changed: 137 additions & 11 deletions

File tree

ch_15/Exercise15_24.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
import javafx.animation.PathTransition;
44
import javafx.animation.Timeline;
55
import javafx.application.Application;
6+
import javafx.collections.ObservableList;
67
import javafx.scene.Scene;
7-
import javafx.scene.Group;
8-
import javafx.scene.layout.BorderPane;
8+
import javafx.scene.layout.Pane;
99
import javafx.scene.paint.Color;
1010
import javafx.scene.shape.Arc;
1111
import javafx.scene.shape.Circle;
12+
import javafx.scene.shape.Line;
13+
import javafx.scene.shape.Polyline;
14+
import javafx.scene.text.Font;
15+
import javafx.scene.text.Text;
1216
import javafx.stage.Stage;
1317
import javafx.util.Duration;
1418

@@ -21,17 +25,16 @@
2125
public class Exercise15_24 extends Application {
2226
@Override
2327
public void start(Stage primaryStage) {
24-
Group group = new Group();
28+
Pane pane = new Pane();
29+
2530
Circle circle = new Circle(0, 0, 10);
2631
circle.setFill(Color.ORANGE);
2732

2833
Arc arc = new Arc(125, 100, 80, 40, 210, 125);
2934
arc.setFill(Color.WHITE);
3035
arc.setStroke(Color.BLACK);
31-
32-
group.getChildren().add(arc);
33-
group.getChildren().add(circle);
34-
36+
pane.getChildren().add(arc);
37+
pane.getChildren().add(circle);
3538
PathTransition pt = new PathTransition();
3639
pt.setDuration(Duration.millis(4000));
3740
pt.setPath(arc);
@@ -40,13 +43,15 @@ public void start(Stage primaryStage) {
4043
PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
4144
pt.setCycleCount(Timeline.INDEFINITE);
4245
pt.setAutoReverse(true);
43-
pt.play(); // Play animation
46+
pt.play();
4447

45-
group.setOnMousePressed(e -> pt.pause());
46-
group.setOnMouseReleased(e -> pt.play());
47-
Scene scene = new Scene(new BorderPane(group), 250, 200);
48+
pane.setOnMousePressed(e -> pt.pause());
49+
pane.setOnMouseReleased(e -> pt.play());
50+
51+
Scene scene = new Scene(pane, 250, 200);
4852
primaryStage.setTitle(getClass().getName());
4953
primaryStage.setScene(scene);
5054
primaryStage.show();
5155
}
5256
}
57+

ch_15/Exercise15_25.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
package ch_15;
22

3+
import javafx.animation.PathTransition;
34
import javafx.application.Application;
5+
import javafx.collections.ObservableList;
6+
import javafx.scene.Scene;
7+
import javafx.scene.input.MouseButton;
8+
import javafx.scene.layout.Pane;
9+
import javafx.scene.shape.Circle;
10+
import javafx.scene.shape.Line;
11+
import javafx.scene.shape.Polyline;
12+
import javafx.scene.text.Font;
13+
import javafx.scene.text.Text;
414
import javafx.stage.Stage;
15+
import javafx.util.Duration;
516

617
/**
718
* **15.25 (Animation: ball on curve) Write a program that animates a ball moving along
@@ -10,8 +21,118 @@
1021
* a click on the left/right mouse button.
1122
*/
1223
public class Exercise15_25 extends Application {
24+
private final double sceneWidth = 600;
25+
private final double sceneHeight = 260;
26+
private final int fontSize = 16;
27+
28+
private final double centerX;
29+
private final double centerY;
30+
31+
public Exercise15_25() {
32+
centerX = sceneWidth / 2;
33+
centerY = sceneHeight / 2;
34+
}
35+
1336
@Override
1437
public void start(Stage primaryStage) throws Exception {
38+
Pane pane = new Pane();
39+
Polyline xAxis = new Polyline();
40+
Polyline yAxis = new Polyline();
41+
drawYAxis(pane, yAxis);
42+
drawXAxis(pane, xAxis);
43+
44+
Polyline polyline1 = new Polyline();
45+
ObservableList<Double> list = polyline1.getPoints();
46+
int startXValue = -170;
47+
int endXValue = 170;
48+
for (int x = startXValue; x <= endXValue; x++) {
49+
list.add(x + centerX);
50+
double y = calculateY(x, centerY);
51+
list.add(y);
52+
if (isYIntersectingXAxis(y, centerY)) {
53+
Text text = new Text(x + centerX, centerY / 0.9, getXAxisLabel(x));
54+
pane.getChildren().add(text);
55+
}
56+
57+
}
58+
Circle point = new Circle(list.get(0), list.get(1), 10);
59+
PathTransition path = new PathTransition(Duration.millis(4000), polyline1, point);
60+
path.setCycleCount(PathTransition.INDEFINITE);
61+
pane.getChildren().addAll(xAxis, yAxis, polyline1, point);
62+
pane.setOnMouseClicked(e -> {
63+
if (e.getButton() == MouseButton.PRIMARY) {
64+
path.play();
65+
} else if (e.getButton() == MouseButton.SECONDARY) {
66+
path.pause();
67+
}
68+
});
69+
primaryStage.setScene(new Scene(pane, sceneWidth, sceneHeight));
70+
primaryStage.setTitle(getClass().getName());
71+
primaryStage.show();
72+
73+
}
74+
75+
private double calculateY(int x, double centerY) {
76+
return centerY - 50 * Math.sin((x / 100.0) * 2 * Math.PI);
77+
}
78+
79+
private boolean isYIntersectingXAxis(double y, double centerY) {
80+
return y - centerY < 0.01 && y - centerY > -0.01;
81+
}
82+
83+
private void drawXAxis(Pane pane, Polyline xAxis) {
84+
ObservableList<Double> xAxisList = xAxis.getPoints();
85+
double limit = sceneWidth * 0.95;
86+
87+
for (double x = 0; x < limit; x++) {
88+
xAxisList.add(x);
89+
xAxisList.add(centerY);
90+
}
1591

92+
Line line1 = new Line(limit, centerY, limit - sceneWidth * 0.05, centerY * 0.875);
93+
Line line2 = new Line(limit, centerY, limit - sceneWidth * 0.05, centerY / 0.875);
94+
Text text = new Text(limit + (sceneWidth * 0.02), centerY, "X");
95+
text.setFont(Font.font(fontSize));
96+
pane.getChildren().addAll(line1, line2, text);
1697
}
98+
99+
private void drawYAxis(Pane pane, Polyline yAxis) {
100+
101+
ObservableList<Double> yAxisList = yAxis.getPoints();
102+
double limit = sceneHeight * 0.95;
103+
104+
for (double y = 0; y < limit; y++) {
105+
yAxisList.add(centerX);
106+
yAxisList.add(y + sceneHeight * 0.1);
107+
108+
}
109+
Line line1 = new Line(centerX, sceneHeight * 0.1, centerX - sceneWidth * 0.03, sceneHeight * 0.22);
110+
Line line2 = new Line(centerX, sceneHeight * 0.1, centerX + sceneWidth * 0.03, sceneHeight * 0.22);
111+
Text text = new Text(limit + (sceneWidth * 0.2), sceneHeight * 0.1, "Y");
112+
text.setFont(Font.font(fontSize));
113+
pane.getChildren().addAll(line1, line2, text);
114+
}
115+
116+
private String getXAxisLabel(double x) {
117+
if (isRoughlyEqual(x, 0)) {
118+
return "0";
119+
} else if (isRoughlyEqual(x, 50)) {
120+
return "π";
121+
} else if (isRoughlyEqual(x, -50)) {
122+
return "-π";
123+
} else if (isRoughlyEqual(x, 100)) {
124+
return "2π";
125+
} else if (isRoughlyEqual(x, -100)) {
126+
return "-2π";
127+
}
128+
129+
return "";
130+
131+
}
132+
133+
private boolean isRoughlyEqual(double a, double b) {
134+
return a - b < 0.01 && a - b > -0.01;
135+
}
136+
17137
}
138+

0 commit comments

Comments
 (0)