*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);@Overridepublic 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));}
}
- 结果展示