**15.20 (几何问題:显示角度)
请编写一个程序,使用户可以拖动一个三角形的顶点,并在三角形改变时动态显示角度,如图15-30a所示。计算角度的公式在程序清单4-1中给出
- 习题思路
- 新建三个圆,三条线和三个文本并添加到面板Pane中
- 将文本和直线的位置分别绑定在三个圆上
- 为circle圆注册一个事件(鼠标拖动:setOnMouseDragged())并同时重新设置文本内容
- 新建几个方法分别计算角度,距离。
示例代码:编程练习题15_20DisplayAngle.java
package chapter_15;
import javafx.application.Application;
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;
public class 编程练习题15_20DisplayAngle extends Application{
private double x1, y1;
private double x2, y2;
private double x3, y3;
Circle c1 = new Circle(x1 = 80, y1 = 50, 6);
Circle c2 = new Circle(x2 = 80, y2 = 160, 6);
Circle c3 = new Circle(x3 = 150, y3 = 100, 6);
Text t1 = new Text("c1");
Text t2 = new Text("c2");
Text t3 = new Text("c3");
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
Line l1 = new Line(x1, y1, x2, y2);
Line l2 = new Line(x1, y1, x3, y3);
Line l3 = new Line(x2, y2, x3, y3);
updateAngleText();
bindTextToCircle(t1, c1);
bindTextToCircle(t2, c2);
bindTextToCircle(t3, c3);
pane.getChildren().addAll(c1, c2, c3, l1, l2, l3, t1, t2, t3);
l1.startXProperty().bind(c1.centerXProperty());
l1.startYProperty().bind(c1.centerYProperty());
l2.startXProperty().bind(c1.centerXProperty());
l2.startYProperty().bind(c1.centerYProperty());
l3.startXProperty().bind(c2.centerXProperty());
l3.startYProperty().bind(c2.centerYProperty());
l1.endXProperty().bind(c2.centerXProperty());
l1.endYProperty().bind(c2.centerYProperty());
l2.endXProperty().bind(c3.centerXProperty());
l2.endYProperty().bind(c3.centerYProperty());
l3.endXProperty().bind(c3.centerXProperty());
l3.endYProperty().bind(c3.centerYProperty());
bindDragEvent(c1, t1);
bindDragEvent(c2, t2);
bindDragEvent(c3, t3);
Scene scene = new Scene(pane, 300, 300);
primaryStage.setTitle("编程练习题15_20DisplayAngle");
primaryStage.setScene(scene);
primaryStage.show();
}
private void bindTextToCircle(Text text, Circle circle) {
text.xProperty().bind(circle.centerXProperty());
text.yProperty().bind(circle.centerYProperty().subtract(5));
}
private void bindDragEvent(Circle circle, Text text) {
circle.setOnMouseDragged(e -> {
circle.setCenterX(e.getX());
circle.setCenterY(e.getY());
updateAngleText();
});
}
private void updateAngleText() {
t1.setText("c1: " + calculateAngle(c1, c2, c3));
t2.setText("c2: " + calculateAngle(c2, c1, c3));
t3.setText("c3: " + calculateAngle(c3, c1, c2));
}
private double calculateAngle(Circle referenceCircle, Circle circle1, Circle circle2) {
double a = distance(referenceCircle, circle1);
double b = distance(referenceCircle, circle2);
double c = distance(circle1, circle2);
double angle = Math.toDegrees(Math.acos((a * a + b * b - c * c) / (2 * a * b)));
return Math.round(angle * 100.0) / 100.0;
}
private double distance(Circle c1, Circle c2) {
return Math.sqrt(Math.pow(c2.getCenterX() - c1.getCenterX(), 2) + Math.pow(c2.getCenterY() - c1.getCenterY(), 2));
}
public static void main(String[] args) {
Application.launch(args);
}
}
- 结果展示