Skip to content

Commit 9b42e03

Browse files
committed
new chapters and exercise solutions
1 parent 4916fc9 commit 9b42e03

12 files changed

+1661
-0
lines changed

ch_15/Exercise15_21.java

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package ch_15;
2+
3+
4+
import javafx.application.Application;
5+
import javafx.geometry.Point2D;
6+
import javafx.scene.Scene;
7+
import javafx.scene.layout.Pane;
8+
import javafx.scene.shape.Circle;
9+
import javafx.scene.shape.Line;
10+
import javafx.scene.text.Text;
11+
import javafx.stage.Stage;
12+
13+
/**
14+
* 15.21 (Drag points) Draw a circle with three random points on the circle. Connect
15+
* the points to form a triangle. Display the angles in the triangle. Use the mouse
16+
* to drag a point along the perimeter of the circle. As you drag it, the triangle and
17+
* angles are redisplayed dynamically, as shown in Figure 15.30b. For computing
18+
* angles in a triangle, see Listing 4.1.
19+
* <p>
20+
* The parametric equation for a circle is
21+
* x = cx + r * cos(a)
22+
* y = cy + r * sin(a)
23+
* where r is the radius, (cx, cy) the center of the circle, and a, an angle in radians.
24+
*/
25+
public class Exercise15_21 extends Application {
26+
private double radius = 10;
27+
private int centerX = 200;
28+
private int centerY = 125;
29+
private int radiusMainCircle = 100;
30+
private Pane pane = new Pane();
31+
private Circle outlineCircle = new Circle(centerX, centerY, radiusMainCircle);
32+
private Circle[] points = new Circle[3];
33+
private Line line1 = new Line();
34+
private Line line2 = new Line();
35+
private Line line3 = new Line();
36+
private Text[] text = {new Text(), new Text(), new Text()};
37+
38+
@Override
39+
public void start(Stage primaryStage) {
40+
draw();
41+
pane.getChildren().addAll(points[0], points[1], points[2],
42+
line1, line2, line3, text[0], text[1], text[2]);
43+
Scene scene = new Scene(pane, 400, 250);
44+
primaryStage.setTitle(getClass().getName());
45+
primaryStage.setScene(scene);
46+
primaryStage.show();
47+
48+
points[0].setOnMouseDragged(e -> {
49+
if (points[0].contains(e.getX(), e.getY())) {
50+
// Recompute and display angles
51+
points[0].setCenterX(e.getX());
52+
points[0].setCenterY(e.getY());
53+
setLines();
54+
}
55+
});
56+
57+
points[1].setOnMouseDragged(e -> {
58+
if (points[1].contains(e.getX(), e.getY())) {
59+
// Recompute and display angles
60+
points[1].setCenterX(e.getX());
61+
points[1].setCenterY(e.getY());
62+
setLines();
63+
}
64+
});
65+
66+
points[2].setOnMouseDragged(e -> {
67+
if (points[2].contains(e.getX(), e.getY())) {
68+
// Recompute and display angles
69+
points[2].setCenterX(e.getX());
70+
points[2].setCenterY(e.getY());
71+
setLines();
72+
}
73+
});
74+
}
75+
76+
77+
void draw() {
78+
points[0] = new Circle(40, 40, 10);
79+
points[1] = new Circle(140, 40, 10);
80+
points[2] = new Circle(60, 140, 10);
81+
setLines();
82+
}
83+
84+
private void setLines() {
85+
line1.setStartX(points[0].getCenterX());
86+
line1.setStartY(points[0].getCenterY());
87+
line1.setEndX(points[1].getCenterX());
88+
line1.setEndY(points[1].getCenterY());
89+
line2.setStartX(points[0].getCenterX());
90+
line2.setStartY(points[0].getCenterY());
91+
line2.setEndX(points[2].getCenterX());
92+
line2.setEndY(points[2].getCenterY());
93+
line3.setStartX(points[1].getCenterX());
94+
line3.setStartY(points[1].getCenterY());
95+
line3.setEndX(points[2].getCenterX());
96+
line3.setEndY(points[2].getCenterY());
97+
98+
// Compute angles
99+
double a = new Point2D(points[2].getCenterX(), points[2].getCenterY()).
100+
distance(points[1].getCenterX(), points[1].getCenterY());
101+
double b = new Point2D(points[2].getCenterX(), points[2].getCenterY()).
102+
distance(points[0].getCenterX(), points[0].getCenterY());
103+
double c = new Point2D(points[1].getCenterX(), points[1].getCenterY()).
104+
distance(points[0].getCenterX(), points[0].getCenterY());
105+
double[] angle = new double[3];
106+
angle[0] = Math.acos((a * a - b * b - c * c) / (-2 * b * c));
107+
angle[1] = Math.acos((b * b - a * a - c * c) / (-2 * a * c));
108+
angle[2] = Math.acos((c * c - b * b - a * a) / (-2 * a * b));
109+
110+
for (int i = 0; i < 3; i++) {
111+
text[i].setX(points[i].getCenterX());
112+
text[i].setY(points[i].getCenterY() - radius);
113+
text[i].setText(String.format("%.2f", Math.toDegrees(angle[i])));
114+
}
115+
}
116+
}

ch_15/Exercise15_29.java

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package ch_15;
2+
3+
import javafx.animation.KeyFrame;
4+
import javafx.animation.Timeline;
5+
import javafx.application.Application;
6+
import javafx.scene.Scene;
7+
import javafx.scene.input.KeyCode;
8+
import javafx.scene.layout.Pane;
9+
import javafx.scene.shape.Circle;
10+
import javafx.scene.shape.Polygon;
11+
import javafx.scene.shape.Rectangle;
12+
import javafx.stage.Stage;
13+
import javafx.util.Duration;
14+
15+
/**
16+
* **15.29 (Racing car) Write a program that simulates car racing, as shown in
17+
* Figure 15.34a. The car moves from left to right. When it hits the right end, it
18+
* restarts from the left and continues the same process. You can use a timer to
19+
* control animation. Redraw the car with a new base coordinates (x, y), as shown
20+
* in Figure 15.34b. Also let the user pause/resume the animation with a
21+
* button press/release and increase/decrease the car speed by pressing the UP and
22+
* DOWN arrow keys.
23+
*/
24+
public class Exercise15_29 extends Application {
25+
26+
private final double WIDTH = 600;
27+
private final double HEIGHT = 100;
28+
29+
@Override
30+
public void start(Stage primaryStage) throws Exception {
31+
RacingPane pane = new RacingPane(WIDTH, HEIGHT);
32+
pane.start();
33+
pane.setOnMousePressed(e -> pane.pause());
34+
pane.setOnMouseReleased(e -> pane.play());
35+
36+
pane.setOnKeyPressed(e -> {
37+
if (e.getCode() == KeyCode.UP) {
38+
pane.increaseSpeed();
39+
} else if (e.getCode() == KeyCode.DOWN) {
40+
pane.decreaseSpeed();
41+
}
42+
});
43+
44+
Scene scene = new Scene(pane, WIDTH, HEIGHT);
45+
primaryStage.setTitle(getClass().getName());
46+
primaryStage.setScene(scene);
47+
primaryStage.show();
48+
49+
pane.requestFocus();
50+
}
51+
52+
}
53+
54+
class RacingPane extends Pane {
55+
private double x;
56+
private double y;
57+
private CarShape car;
58+
private Timeline animation;
59+
60+
/**
61+
* Construct and animate a default CarPane
62+
*/
63+
RacingPane(double width, double height) {
64+
setHeight(height);
65+
setWidth(width);
66+
car = new CarShape(x, y, 5, this);
67+
x = 0;
68+
y = 100;
69+
animation = new Timeline(
70+
new KeyFrame(Duration.millis(50), e -> car.moveCar(x, y, this)));
71+
animation.setCycleCount(Timeline.INDEFINITE);
72+
}
73+
74+
75+
void start() {
76+
animation.play();
77+
}
78+
79+
80+
/**
81+
* Pause animation
82+
*/
83+
public void pause() {
84+
animation.pause();
85+
}
86+
87+
/**
88+
* Play animation
89+
*/
90+
public void play() {
91+
animation.play();
92+
}
93+
94+
/**
95+
* Increase rate by 1
96+
*/
97+
public void increaseSpeed() {
98+
animation.setRate(animation.getRate() + 1);
99+
}
100+
101+
/**
102+
* decrease rate by 1
103+
*/
104+
public void decreaseSpeed() {
105+
animation.setRate(animation.getRate() > 0 ? animation.getRate() - 1 : 0);
106+
}
107+
108+
class CarShape {
109+
private double wheelRadius;
110+
private Rectangle lowerBody;
111+
private Polygon topBody;
112+
private Circle wheel1;
113+
private Circle wheel2;
114+
115+
public CarShape(double x, double y, double wheelRadius, Pane pane) {
116+
this.wheelRadius = wheelRadius;
117+
drawAndRender(x, y, pane);
118+
}
119+
120+
void drawAndRender(double x, double y, Pane pane) {
121+
if (!pane.getChildren().isEmpty()) {
122+
pane.getChildren().clear();
123+
}
124+
125+
lowerBody = new Rectangle(x, y - 20, 50, 10);
126+
topBody = new Polygon(x + 10, y - 20, x + 20, y - 30, x + 30,
127+
y - 30, x + 40, y - 20);
128+
wheel1 = new Circle(x + 15, y - 5, wheelRadius);
129+
wheel2 = new Circle(x + 35, y - 5, wheelRadius);
130+
pane.getChildren().addAll(getLowerBody(), getWheel1(), getWheel2(), getTopBody());
131+
}
132+
133+
/**
134+
* Calculate new x position and draw car
135+
*
136+
* @param x the current x position
137+
* @param y the current y position
138+
* @param pane the pane to render the car on
139+
*/
140+
protected void moveCar(double x, double y, Pane pane) {
141+
x += 1;
142+
143+
144+
drawAndRender(x, y, pane);
145+
}
146+
147+
public Rectangle getLowerBody() {
148+
return lowerBody;
149+
}
150+
151+
public Polygon getTopBody() {
152+
return topBody;
153+
}
154+
155+
public Circle getWheel1() {
156+
return wheel1;
157+
}
158+
159+
public Circle getWheel2() {
160+
return wheel2;
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)