*15.21(拖动点)
绘制一个圆,在圆上有三个随机点。连接这些点构成一个三角形。显示三角形中的角度。使用鼠标沿着圆的边拖动点。拖动的时候,三角形以及角度动态地重新显示,如图15-30b 所示。计算三角形角度的公式参考程序清单4-1
可以参考上一题:Java语言程序设计基础篇_编程练习题**15.20 (几何问題:显示角度)-CSDN博客
- 习题思路
- 新建一个大圆,生成三个随机角度,在大圆上对应角度创建三个小圆,同时创建三个文本和三条线
- 将文本和直线的位置分别绑定在三个圆上
- 为三个小圆注册鼠标事件,为避免重复书写代码,可以建一个方法来注册
- (注册事件内部)计算鼠标相对于大圆中心的角度,然后再计算出xy的坐标,设置到小圆上,同时更新文本内容
- 新建其他几个方法分别计算角度与距离(与上一题一样,书上已给出公式)
代码示例:编程练习题15_21MovePoint.java
package chapter_15;
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 编程练习题15_21MovePoint extends Application{
Circle bigCircle = new Circle(150, 150, 100);
Text t1 = new Text("c1");
Text t2 = new Text("c2");
Text t3 = new Text("c3");
double randomAngle1 = Math.random()*2*Math.PI;
double randomAngle2 = Math.random()*2*Math.PI;
double randomAngle3 = Math.random()*2*Math.PI;
double x1 = bigCircle.getCenterX() + bigCircle.getRadius()*Math.cos(randomAngle1);
double y1 = bigCircle.getCenterY() + bigCircle.getRadius()*Math.sin(randomAngle1);
double x2 = bigCircle.getCenterX() + bigCircle.getRadius()*Math.cos(randomAngle2);
double y2 = bigCircle.getCenterY() + bigCircle.getRadius()*Math.sin(randomAngle2);
double x3 = bigCircle.getCenterX() + bigCircle.getRadius()*Math.cos(randomAngle3);
double y3 = bigCircle.getCenterY() + bigCircle.getRadius()*Math.sin(randomAngle3);
Circle c1 = new Circle(x1, y1, 10);
Circle c2 = new Circle(x2, y2, 10);
Circle c3 = new Circle(x3, y3, 10);
@Override
public void start(Stage primaryStage) throws Exception {
Pane pane = new Pane();
bigCircle.setFill(Color.WHITE);
bigCircle.setStroke(Color.BLACK);
pane.getChildren().add(bigCircle);
c1.setFill(Color.TRANSPARENT);
c2.setFill(Color.TRANSPARENT);
c3.setFill(Color.TRANSPARENT);
c1.setStroke(Color.BLACK);
c2.setStroke(Color.BLACK);
c3.setStroke(Color.BLACK);
pane.getChildren().addAll(c1, c2, c3);
bindTextToCircle(t1, c1);
bindTextToCircle(t2, c2);
bindTextToCircle(t3, c3);
Line l1 = new Line(x1, y1, x2, y2);
Line l2 = new Line(x1, y1, x3, y3);
Line l3 = new Line(x2, y2, x3, y3);
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);
bindDragEvent(c2);
bindDragEvent(c3);
updateAngleText();
pane.getChildren().addAll(l1, l2, l3,t1,t2,t3);
Scene scene = new Scene(pane, 300, 300);
primaryStage.setTitle("编程练习题15_21MovePoint");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
private void bindDragEvent(Circle c) {
c.setOnMouseDragged(e -> {
double mouseX = e.getX();
double mouseY = e.getY();
double deltaX = mouseX - bigCircle.getCenterX();
double deltaY = mouseY - bigCircle.getCenterY();
double angle = Math.atan2(deltaY, deltaX);
double x = bigCircle.getCenterX() + bigCircle.getRadius()*Math.cos(angle);
double y = bigCircle.getCenterY() + bigCircle.getRadius()*Math.sin(angle);
c.setCenterX(x);
c.setCenterY(y);
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 void bindTextToCircle(Text text, Circle circle) {
text.xProperty().bind(circle.centerXProperty());
text.yProperty().bind(circle.centerYProperty().subtract(5));
}
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));
}
}
- 结果展示