Java语言程序设计基础篇_编程练习题*15.21(拖动点)

*15.21(拖动点)

绘制一个圆,在圆上有三个随机点。连接这些点构成一个三角形。显示三角形中的角度。使用鼠标沿着圆的边拖动点。拖动的时候,三角形以及角度动态地重新显示,如图15-30b 所示。计算三角形角度的公式参考程序清单4-1

可以参考上一题:Java语言程序设计基础篇_编程练习题**15.20 (几何问題:显示角度)-CSDN博客 

  • 习题思路
  1.  新建一个大圆,生成三个随机角度,在大圆上对应角度创建三个小圆,同时创建三个文本和三条线
  2. 将文本和直线的位置分别绑定在三个圆上
  3. 为三个小圆注册鼠标事件,为避免重复书写代码,可以建一个方法来注册
  4. (注册事件内部)计算鼠标相对于大圆中心的角度,然后再计算出xy的坐标,设置到小圆上,同时更新文本内容
  5. 新建其他几个方法分别计算角度与距离(与上一题一样,书上已给出公式)

代码示例:编程练习题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));
		    }
}
  •  结果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值