-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from HarryDulaney/hg-new-solutions
Add many new solutions
- Loading branch information
Showing
12 changed files
with
1,669 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package ch_15; | ||
|
||
|
||
import javafx.application.Application; | ||
import javafx.geometry.Point2D; | ||
import javafx.scene.Scene; | ||
import javafx.scene.layout.Pane; | ||
import javafx.scene.shape.Circle; | ||
import javafx.scene.shape.Line; | ||
import javafx.scene.text.Text; | ||
import javafx.stage.Stage; | ||
|
||
/** | ||
* 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. | ||
* <p> | ||
* The parametric equation for a circle is | ||
* x = cx + r * cos(a) | ||
* y = cy + r * sin(a) | ||
* where r is the radius, (cx, cy) the center of the circle, and a, an angle in radians. | ||
*/ | ||
public class Exercise15_21 extends Application { | ||
private double radius = 10; | ||
private int centerX = 200; | ||
private int centerY = 125; | ||
private int radiusMainCircle = 100; | ||
private Pane pane = new Pane(); | ||
private Circle outlineCircle = new Circle(centerX, centerY, radiusMainCircle); | ||
private Circle[] points = new Circle[3]; | ||
private Line line1 = new Line(); | ||
private Line line2 = new Line(); | ||
private Line line3 = new Line(); | ||
private Text[] text = {new Text(), new Text(), new Text()}; | ||
|
||
@Override | ||
public void start(Stage primaryStage) { | ||
draw(); | ||
pane.getChildren().addAll(points[0], points[1], points[2], | ||
line1, line2, line3, text[0], text[1], text[2]); | ||
Scene scene = new Scene(pane, 400, 250); | ||
primaryStage.setTitle(getClass().getName()); | ||
primaryStage.setScene(scene); | ||
primaryStage.show(); | ||
|
||
points[0].setOnMouseDragged(e -> { | ||
if (points[0].contains(e.getX(), e.getY())) { | ||
// Recompute and display angles | ||
points[0].setCenterX(e.getX()); | ||
points[0].setCenterY(e.getY()); | ||
setLines(); | ||
} | ||
}); | ||
|
||
points[1].setOnMouseDragged(e -> { | ||
if (points[1].contains(e.getX(), e.getY())) { | ||
// Recompute and display angles | ||
points[1].setCenterX(e.getX()); | ||
points[1].setCenterY(e.getY()); | ||
setLines(); | ||
} | ||
}); | ||
|
||
points[2].setOnMouseDragged(e -> { | ||
if (points[2].contains(e.getX(), e.getY())) { | ||
// Recompute and display angles | ||
points[2].setCenterX(e.getX()); | ||
points[2].setCenterY(e.getY()); | ||
setLines(); | ||
} | ||
}); | ||
} | ||
|
||
|
||
void draw() { | ||
points[0] = new Circle(40, 40, 10); | ||
points[1] = new Circle(140, 40, 10); | ||
points[2] = new Circle(60, 140, 10); | ||
setLines(); | ||
} | ||
|
||
private void setLines() { | ||
line1.setStartX(points[0].getCenterX()); | ||
line1.setStartY(points[0].getCenterY()); | ||
line1.setEndX(points[1].getCenterX()); | ||
line1.setEndY(points[1].getCenterY()); | ||
line2.setStartX(points[0].getCenterX()); | ||
line2.setStartY(points[0].getCenterY()); | ||
line2.setEndX(points[2].getCenterX()); | ||
line2.setEndY(points[2].getCenterY()); | ||
line3.setStartX(points[1].getCenterX()); | ||
line3.setStartY(points[1].getCenterY()); | ||
line3.setEndX(points[2].getCenterX()); | ||
line3.setEndY(points[2].getCenterY()); | ||
|
||
// Compute angles | ||
double a = new Point2D(points[2].getCenterX(), points[2].getCenterY()). | ||
distance(points[1].getCenterX(), points[1].getCenterY()); | ||
double b = new Point2D(points[2].getCenterX(), points[2].getCenterY()). | ||
distance(points[0].getCenterX(), points[0].getCenterY()); | ||
double c = new Point2D(points[1].getCenterX(), points[1].getCenterY()). | ||
distance(points[0].getCenterX(), points[0].getCenterY()); | ||
double[] angle = new double[3]; | ||
angle[0] = Math.acos((a * a - b * b - c * c) / (-2 * b * c)); | ||
angle[1] = Math.acos((b * b - a * a - c * c) / (-2 * a * c)); | ||
angle[2] = Math.acos((c * c - b * b - a * a) / (-2 * a * b)); | ||
|
||
for (int i = 0; i < 3; i++) { | ||
text[i].setX(points[i].getCenterX()); | ||
text[i].setY(points[i].getCenterY() - radius); | ||
text[i].setText(String.format("%.2f", Math.toDegrees(angle[i]))); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package ch_15; | ||
|
||
import javafx.animation.KeyFrame; | ||
import javafx.animation.Timeline; | ||
import javafx.application.Application; | ||
import javafx.scene.Scene; | ||
import javafx.scene.input.KeyCode; | ||
import javafx.scene.layout.Pane; | ||
import javafx.scene.shape.Circle; | ||
import javafx.scene.shape.Polygon; | ||
import javafx.scene.shape.Rectangle; | ||
import javafx.stage.Stage; | ||
import javafx.util.Duration; | ||
|
||
/** | ||
* **15.29 (Racing car) Write a program that simulates car racing, as shown in | ||
* Figure 15.34a. The car moves from left to right. When it hits the right end, it | ||
* restarts from the left and continues the same process. You can use a timer to | ||
* control animation. Redraw the car with a new base coordinates (x, y), as shown | ||
* in Figure 15.34b. Also let the user pause/resume the animation with a | ||
* button press/release and increase/decrease the car speed by pressing the UP and | ||
* DOWN arrow keys. | ||
*/ | ||
public class Exercise15_29 extends Application { | ||
|
||
private final double WIDTH = 600; | ||
private final double HEIGHT = 100; | ||
|
||
@Override | ||
public void start(Stage primaryStage) throws Exception { | ||
RacingPane pane = new RacingPane(WIDTH, HEIGHT); | ||
pane.start(); | ||
pane.setOnMousePressed(e -> pane.pause()); | ||
pane.setOnMouseReleased(e -> pane.play()); | ||
|
||
pane.setOnKeyPressed(e -> { | ||
if (e.getCode() == KeyCode.UP) { | ||
pane.increaseSpeed(); | ||
} else if (e.getCode() == KeyCode.DOWN) { | ||
pane.decreaseSpeed(); | ||
} | ||
}); | ||
|
||
Scene scene = new Scene(pane, WIDTH, HEIGHT); | ||
primaryStage.setTitle(getClass().getName()); | ||
primaryStage.setScene(scene); | ||
primaryStage.show(); | ||
|
||
pane.requestFocus(); | ||
} | ||
|
||
} | ||
|
||
class RacingPane extends Pane { | ||
private double x; | ||
private double y; | ||
private CarShape car; | ||
private Timeline animation; | ||
|
||
/** | ||
* Construct and animate a default CarPane | ||
*/ | ||
RacingPane(double width, double height) { | ||
setHeight(height); | ||
setWidth(width); | ||
car = new CarShape(x, y, 5, this); | ||
x = 0; | ||
y = 100; | ||
animation = new Timeline( | ||
new KeyFrame(Duration.millis(50), e -> car.moveCar(x, y, this))); | ||
animation.setCycleCount(Timeline.INDEFINITE); | ||
} | ||
|
||
|
||
void start() { | ||
animation.play(); | ||
} | ||
|
||
|
||
/** | ||
* Pause animation | ||
*/ | ||
public void pause() { | ||
animation.pause(); | ||
} | ||
|
||
/** | ||
* Play animation | ||
*/ | ||
public void play() { | ||
animation.play(); | ||
} | ||
|
||
/** | ||
* Increase rate by 1 | ||
*/ | ||
public void increaseSpeed() { | ||
animation.setRate(animation.getRate() + 1); | ||
} | ||
|
||
/** | ||
* decrease rate by 1 | ||
*/ | ||
public void decreaseSpeed() { | ||
animation.setRate(animation.getRate() > 0 ? animation.getRate() - 1 : 0); | ||
} | ||
|
||
class CarShape { | ||
private double wheelRadius; | ||
private Rectangle lowerBody; | ||
private Polygon topBody; | ||
private Circle wheel1; | ||
private Circle wheel2; | ||
|
||
public CarShape(double x, double y, double wheelRadius, Pane pane) { | ||
this.wheelRadius = wheelRadius; | ||
drawAndRender(x, y, pane); | ||
} | ||
|
||
void drawAndRender(double x, double y, Pane pane) { | ||
if (!pane.getChildren().isEmpty()) { | ||
pane.getChildren().clear(); | ||
} | ||
|
||
lowerBody = new Rectangle(x, y - 20, 50, 10); | ||
topBody = new Polygon(x + 10, y - 20, x + 20, y - 30, x + 30, | ||
y - 30, x + 40, y - 20); | ||
wheel1 = new Circle(x + 15, y - 5, wheelRadius); | ||
wheel2 = new Circle(x + 35, y - 5, wheelRadius); | ||
pane.getChildren().addAll(getLowerBody(), getWheel1(), getWheel2(), getTopBody()); | ||
} | ||
|
||
/** | ||
* Calculate new x position and draw car | ||
* | ||
* @param x the current x position | ||
* @param y the current y position | ||
* @param pane the pane to render the car on | ||
*/ | ||
protected void moveCar(double x, double y, Pane pane) { | ||
x += 1; | ||
|
||
|
||
drawAndRender(x, y, pane); | ||
} | ||
|
||
public Rectangle getLowerBody() { | ||
return lowerBody; | ||
} | ||
|
||
public Polygon getTopBody() { | ||
return topBody; | ||
} | ||
|
||
public Circle getWheel1() { | ||
return wheel1; | ||
} | ||
|
||
public Circle getWheel2() { | ||
return wheel2; | ||
} | ||
} | ||
} |
Oops, something went wrong.