【JAVAFX】雷达扫描、拖尾、目标点动态显示

package sample;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RadarMonitor extends Application {

    private static final int WIDTH = 400;
    private static final int HEIGHT = 400;
    private static final double CENTER_X = WIDTH / 2;
    private static final double CENTER_Y = HEIGHT / 2;
    private static final double RADIUS = 150;
    private double angle = 0;
    private List<Double> lineXHistory = new ArrayList<>();
    private List<Double> lineYHistory = new ArrayList<>();
    private double targetX;
    private double targetY;
    private Random random = new Random();
    private long targetUpdateInterval = 500_000_000; // 每500毫秒更新一次目标位置
    private long lastTargetUpdateTime = 0;

    @Override
    public void start(Stage primaryStage) {
        Canvas canvas = new Canvas(WIDTH, HEIGHT);
        GraphicsContext gc = canvas.getGraphicsContext2D();

        // 初始化目标位置
        resetTargetPosition();

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                gc.setFill(Color.BLACK);
                gc.fillRect(0, 0, WIDTH, HEIGHT);

                // 绘制雷达的圆形屏幕
                gc.setStroke(Color.GREEN);
                gc.setLineWidth(2);
                gc.strokeOval(CENTER_X - RADIUS, CENTER_Y - RADIUS, 2 * RADIUS, 2 * RADIUS);

                // 绘制扫描线和扫尾效果
                drawScanLine(gc);

                // 绘制目标
                gc.setFill(Color.RED);
                gc.fillOval(targetX - 5, targetY - 5, 10, 10);

                // 更新扫描线的角度
                angle += 1;
                if (angle >= 360) {
                    angle = 0;
                }

                // 更新目标位置
                updateTargetPosition(now);
            }
        };

        Group root = new Group(canvas);
        Scene scene = new Scene(root, WIDTH, HEIGHT);

        primaryStage.setTitle("雷达监控画面");
        primaryStage.setScene(scene);
        primaryStage.show();

        timer.start();
    }

    private void drawScanLine(GraphicsContext gc) {
        lineXHistory.add(CENTER_X + RADIUS * Math.cos(Math.toRadians(angle)));
        lineYHistory.add(CENTER_Y + RADIUS * Math.sin(Math.toRadians(angle)));

        for (int i = 0; i < lineXHistory.size(); i++) {
            double alpha = 1.0 - (double) i / lineXHistory.size();
            gc.setStroke(Color.color(1, 1, 0, alpha));
            gc.setLineWidth(1);
            gc.strokeLine(CENTER_X, CENTER_Y, lineXHistory.get(i), lineYHistory.get(i));
        }

        // 限制历史记录的长度,以避免占用过多内存
        if (lineXHistory.size() > 100) {
            lineXHistory.remove(0);
            lineYHistory.remove(0);
        }
    }

    private void resetTargetPosition() {
        targetX = CENTER_X + random.nextDouble() * RADIUS * 2 - RADIUS;
        targetY = CENTER_Y + random.nextDouble() * RADIUS * 2 - RADIUS;
    }

    private void updateTargetPosition(long now) {
        if (now - lastTargetUpdateTime >= targetUpdateInterval) {
            resetTargetPosition();
            lastTargetUpdateTime = now;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值