用swing写点在矩形内做弓形运动

本文介绍了一个使用Java实现的点运动模拟程序。该程序通过调整方向和速度来模拟一个点在一个限定区域内的运动轨迹,并利用Swing图形库进行可视化展示。文章包含完整的源代码,展示了如何在二维平面上绘制运动轨迹。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点运动的类MotionTrace.java

 

package org.lyw.sh.test;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Ellipse2D;
import java.text.DecimalFormat;

public class MotionTrace {

	private static int count = 0;

	private static boolean runFlag = true;

	private double startX;
	private double startY;

	private double minX;
	private double minY;

	private double maxX;
	private double maxY;

	private double increase = 0.0;

	private double distance;

	private double rate;

	private double directionX = 1.0;

	private double directionY = 1.0;

	public MotionTrace() {
		startX = 0;
		startY = 0;

		minX = 0;
		minY = 0;

		maxX = 500.0;
		maxY = 500.0;

		distance = 30;

		rate = 0.000009;
	}

	public void directionY(Graphics2D g2d) {
		System.err.println("--------------Y:" + directionY + "--------------");
		// --------------(+0.000000,0.000000+)--------------
		// --------------(+0.009000,0.009000+)--------------
		// System.out.println("--------------(+" + doubleFormat(minX * rate) +
		// ","
		// + doubleFormat(minY * rate) + "+)--------------");
		// System.out.println("--------------(+" + doubleFormat(maxX * rate) +
		// ","
		// + doubleFormat(maxY * rate) + "+)--------------");

		if (startX > maxX) {
			directionX = -directionX;
			startX = startX + distance * directionX;
			count = 1;
			runFlag = false;
			return;
			// directionX();
		} else if (startX < minX) {
			count = 1;
			directionX = -directionX;
			startX = startX + distance * directionX;
			// directionX();
			runFlag = false;
			return;
		}

		if (0 == count) {

			increase = startY;

		} else {

			increase = startY + distance * count * directionY;
		}

		if (!isBeyond(increase, minY, maxY)) {
			Paint paint = new GradientPaint(0, 0, Color.RED, 222, 222,
					Color.green, true);
			g2d.setPaint(paint);
			Ellipse2D circle = new Ellipse2D.Double(startX, increase, 4, 4);
			g2d.draw(circle);

			System.err.println("(" + doubleFormat(startX * rate) + ","
					+ doubleFormat(increase * rate) + ")");
		} else {
			count = -1;
			directionY = -directionY;
			startY = increase + distance * directionY;
			startX = startX + distance * directionX;
			//
			// if (startX > maxX) {
			// directionX = -directionX;
			// startX = startX + distance * directionX;
			// count = 0;
			// directionX();
			// } else if (startX < minX) {
			// count = 0;
			// directionX = -directionX;
			// startX = startX + distance * directionX;
			// directionX();
			// }

		}
		// } else if (increase > maxY) {
		// System.err.println("TOP");
		// count = 1;
		// directionY = -directionY;
		// startY = increase + distance * directionY;
		// startX = startX + distance * directionX;
		// } else if (increase < minY) {
		// System.err.println("BUTTON");
		// count = 1;
		// directionY = -directionY;
		// startY = increase + distance * directionY;
		// startX = startX + distance * directionX;
		// }
		count++;
	}

	public void directionX(Graphics2D g2d) {
		System.err.println("--------------X:" + directionX + "--------------");
		// --------------(+0.000000,0.000000+)--------------
		// --------------(+0.009000,0.009000+)--------------
		// System.out.println("--------------(+" + doubleFormat(minX * rate) +
		// ","
		// + doubleFormat(minY * rate) + "+)--------------");
		// System.out.println("--------------(+" + doubleFormat(maxX * rate) +
		// ","
		// + doubleFormat(maxY * rate) + "+)--------------");

		if (startY > maxY) {
			directionY = -directionY;
			startY = startY + distance * directionY;
			count = 1;
			runFlag = true;
			return;
			// directionY();
		} else if (startY < minY) {
			count = 1;
			directionY = -directionY;
			startY = startY + distance * directionY;
			runFlag = true;
			return;
			// directionY();
		}

		if (0 == count) {

			increase = startX;

		} else {

			increase = startX + distance * count * directionX;
		}

		if (!isBeyond(increase, minX, maxX)) {

			System.err.println("(" + doubleFormat(increase * rate) + ","
					+ doubleFormat(startY * rate) + ")");
		} else {
			// System.err.println("BEYOND");
			count = -1;
			directionX = -directionX;
			startX = increase + distance * directionX;
			startY = startY + distance * directionY;

			// if (startY > maxY) {
			// directionY = -directionY;
			// startY = startY + distance * directionY;
			// count = 0;
			// directionY();
			// } else if (startY < minY) {
			// count = 0;
			// directionY = -directionY;
			// startY = startY + distance * directionY;
			// directionY();
			// }
		}
		// } else if (increase > maxX) {
		// System.err.println("TOP");
		// count = 1;
		// directionX = -directionX;
		// startX = increase + distance * directionX;
		// startY = startY + distance * directionY;
		// } else if (increase < minX) {
		// System.err.println("BUTTON");
		// count = 1;
		// directionX = -directionX;
		// startX = increase + distance * directionX;
		// startY = startY + distance * directionY;
		// }
		count++;
	}

	private String doubleFormat(double dbl) {

		DecimalFormat dft = new DecimalFormat("#####0.000000");

		return dft.format(dbl);
	}

	private boolean isBeyond(double ori, double min, double max) {

		if (ori < min || ori > max) {
			return true;
		}
		return false;

	}

	public double getDirectionX() {
		return directionX;
	}

	public void setDirectionX(double directionX) {
		this.directionX = directionX;
	}

	public double getDirectionY() {
		return directionY;
	}

	public void setDirectionY(double directionY) {
		this.directionY = directionY;
	}

	public static boolean isRunFlag() {
		return runFlag;
	}

	public static void setRunFlag(boolean runFlag) {
		MotionTrace.runFlag = runFlag;
	}

}

 swing画图,显示点的运动MotionRun.java

 

package org.lyw.sh.test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Calendar;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

public class MotionRun {

	public static void main(String[] args) {
		ClockFrame cf = new ClockFrame();
		cf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		cf.setVisible(true);
	}

}

class ClockFrame extends JFrame {
	private static final long serialVersionUID = 1L;

	private ClockPanel panel;
	private Calendar calendar;

	public ClockFrame() {
		setTitle("Clock");
		// setResizable(false);

		this.setBounds(0, 0, 5000, 5000);
		// Toolkit kit = Toolkit.getDefaultToolkit();
		// Dimension screen = kit.getScreenSize();
		// int screenX = screen.width;
		// int screenY = screen.height;
		// setLocation(screenX / 3, screenY / 3);
		final MotionTrace motion = new MotionTrace();
		ActionListener listener = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				calendar = getClock();

				String h = String.valueOf(calendar.get(Calendar.HOUR_OF_DAY));
				String m = String.valueOf(calendar.get(Calendar.MINUTE));
				String s = String.valueOf(calendar.get(Calendar.SECOND));

				TextPanel tp = new TextPanel(h, m, s);
				add(tp, BorderLayout.NORTH);

				panel = new ClockPanel(h, m, s, motion);
				add(panel, BorderLayout.CENTER);

				pack();
			}
		};

		Timer timer = new Timer(1000, listener);
		timer.start();
	}

	public Calendar getClock() {
		Calendar calendar = Calendar.getInstance();
		return calendar;
	}
}

class TextPanel extends JPanel {
	private static final long serialVersionUID = 1L;

	private JTextField hourField;
	private JTextField minuteField;
	private JTextField secondField;

	public TextPanel(String h, String m, String s) {
		setBackground(Color.WHITE);

		add(new JLabel("Hour:"));
		hourField = new JTextField(h, 3);
		hourField.setEditable(false);
		add(hourField);

		add(new JLabel("Minute:"));
		minuteField = new JTextField(m, 3);
		minuteField.setEditable(false);
		add(minuteField);

		add(new JLabel("Second:"));
		secondField = new JTextField(s, 3);
		secondField.setEditable(false);
		add(secondField);
	}
}

class ClockPanel extends JPanel {
	private static final long serialVersionUID = 1L;

	private double seconds = 0;
	private double minutes = 0;
	private double hours = 0;

	private int RADIUS = 100;

	private double SECOND_HAND_LENGTH = 0.8 * RADIUS;
	private double MINUTE_HAND_LENGTH = 0.8 * RADIUS;
	private double HOUR_HAND_LENGTH = 0.7 * RADIUS;

	private int centerX = 0;
	private int centerY = 0;
	MotionTrace motion;

	public ClockPanel(String h, String m, String s, MotionTrace motion) {
		setBackground(Color.BLACK);

		hours = Double.parseDouble(h);
		minutes = Double.parseDouble(m);
		seconds = Double.parseDouble(s);
		this.motion = motion;

		// setPreferredSize(new Dimension(2 * RADIUS + 100, 2 * RADIUS + 100));
		setPreferredSize(new Dimension(5000, 5000));
	}

	public void paintComponent(Graphics g) {

		super.paintComponent(g);
		Graphics2D gs = (Graphics2D) g;

		// --------------------------

		if (MotionTrace.isRunFlag()) {
			motion.directionY(gs);
		} else {
			motion.directionX(gs);
		}
		// --------------------------

		centerX = this.getWidth() / 2;
		centerY = this.getHeight() / 2;

		gs.setColor(Color.GREEN);
		gs.drawString("MAN 表", centerX - 20, centerY - RADIUS / 2);
		gs.drawString("MADE IN CHINA", centerX - 40, centerY + RADIUS / 2);

		gs.setColor(Color.WHITE);
		for (double nlLoop = 0; nlLoop <= 2; nlLoop = nlLoop + 0.1) {
			Ellipse2D circle = new Ellipse2D.Double(centerX - RADIUS + 15
					+ nlLoop, centerY - RADIUS + 15 + nlLoop,
					2 * (RADIUS - 15), 2 * (RADIUS - 15));
			gs.draw(circle);
		}
		for (double nlLoop = 0; nlLoop <= 2; nlLoop = nlLoop + 0.1) {
			Ellipse2D circle = new Ellipse2D.Double(centerX - RADIUS - 9
					+ nlLoop, centerY - RADIUS - 9 + nlLoop, 2 * (RADIUS + 9),
					2 * (RADIUS + 9));
			gs.draw(circle);
		}

		String[] timer = { "Ⅰ", "Ⅱ", "Ⅲ", "Ⅳ", "Ⅴ", "Ⅵ", "Ⅶ", "Ⅷ", "Ⅸ", "Ⅹ",
				"Ⅺ", "Ⅻ" };
		gs.setColor(Color.RED);
		int gX = centerX - 3;
		int gY = centerY - RADIUS + 5;
		for (int i = 0; i < 12; i++) {
			int x = (int) (gX + RADIUS * Math.sin(2 * Math.PI * (i + 1) / 12));
			int y = (int) (gY + RADIUS
					* (1.0 - Math.cos(2 * Math.PI * (i + 1) / 12)));

			gs.drawString(timer[i], x, y);
		}

		double secondAngle = Math.toRadians(360 * seconds / 60);
		drawHand(gs, secondAngle, SECOND_HAND_LENGTH, "s");

		double minuteAngle = Math
				.toRadians(360 * (minutes + seconds / 60) / 60);
		drawHand(gs, minuteAngle, MINUTE_HAND_LENGTH, "m");

		double hourAngle = Math.toRadians(360 * (hours - 12) / 12 + 360
				* minutes / (60 * 12));
		drawHand(gs, hourAngle, HOUR_HAND_LENGTH, "h");
	}

	private void drawHand(Graphics2D gc, double angle, double hand, String l) {
		Point2D center = new Point2D.Double(centerX, centerY);
		Point2D end = new Point2D.Double(centerX + hand * Math.sin(angle),
				centerY - hand * Math.cos(angle));
		if (l.equals("h")) {
			gc.setColor(Color.RED);
		} else if (l.equals("m")) {
			gc.setColor(Color.green);
		} else if (l.equals("s")) {
			gc.setColor(Color.BLUE);
		}
		gc.draw(new Line2D.Double(center, end));
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值