物体的移动 [英] Moving of an object

查看:43
本文介绍了物体的移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任务如下:蚂蚁在其居住区域的一个地方(例如,[0; 0])以速度 V 沿直线移动,然后以相同的速度返回它们的出生点.物体的移动.物体必须停在某个点,然后回到起点.我应该如何修复我的代码?我写的一些代码:

Here is the task: Ants move in one place in the region of their residence (for example, [0; 0]) in a straight line with a speed V, and then turn back to the point of their birth with the same speed.I have problems with the moving of objects. The object must stop at the certain point and go back to starting point. How should I fix my code? Some code I have written:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;

class vThread extends Thread{
public void run(){
    new LabSevenFirst();
    System.out.println(Thread.currentThread().getName());
}

}

public class LabSevenFirst extends JPanel implements ActionListener {
private JFrame fr;
double x = 10;
double y = 10;
double r = 10;
public static double T=0, V;
private float x1, y1, x2, y2, xc, yc;
private int t0;
private Timer timer;
private JButton start, stop, apply;
private JLabel forx1, fory1, forx2, fory2, forV;
private JTextField fx1, fy1, fx2, fy2, fV;


public static void main(String[] args) throws InterruptedException {

    vThread mt = new vThread();
    mt.setName("Ants-labours");
    mt.start();

   Thread.yield();//позволяет досрочно завершить квант времени текущей нити
    Thread.sleep(3000);
    System.out.println(Thread.currentThread().getName());
}

LabSevenFirst() {

    t0 = 1000/60;
    timer = new Timer(t0, this);
    timer.setActionCommand("timer");
    fr = new JFrame("Movement of ants-labours");
    fr.setLayout(null);
    fr.setSize(600, 600);
    fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 50, 300, 300);
    start = new JButton("Start");
    stop = new JButton("Stop");
    apply = new JButton("Apply");
    forx1 = new JLabel("x1");
    fory1 = new JLabel("y1");
    forx2 = new JLabel("x2");
    fory2 = new JLabel("y2");
    forV = new JLabel("V");
    fx1 = new JTextField(x1 + "");
    fy1 = new JTextField(y1 + "");
    fx2 = new JTextField(x2 + "");
    fy2 = new JTextField(y2 + "");
    fV = new JTextField(V + "");
    forx1.setBounds(5, 380, 20, 20);
    fory1.setBounds(5, 400, 20, 20);
    forx2.setBounds(5, 420, 20, 20);
    fory2.setBounds(5, 440, 20, 20);
    forV.setBounds(5, 460, 20, 20);
    fx1.setBounds(30, 380, 40, 20);
    fy1.setBounds(30, 400, 40, 20);
    fx2.setBounds(30, 420, 40, 20);
    fy2.setBounds(30, 440, 40, 20);
    fV.setBounds(30, 460, 40, 20);
    start.setActionCommand("start");
    stop.setActionCommand("stop");
    apply.setActionCommand("apply");
    start.addActionListener(this);
    stop.addActionListener(this);
    apply.addActionListener(this);
    start.setBounds(300, 430, 80, 20);
    stop.setBounds(390, 430, 80, 20);
    apply.setBounds(210, 430, 80, 20);
    fr.add(this);
    fr.add(start);
    fr.add(stop);
    fr.add(apply);
    fr.add(forx1);
    fr.add(fory1);
    fr.add(forx2);
    fr.add(fory2);
    fr.add(forV);
    fr.add(fx1);
    fr.add(fy1);
    fr.add(fx2);
    fr.add(fy2);
    fr.add(fV);
    fr.setVisible(true);
}

@Override
protected void paintComponent(Graphics g) {

    int width = getWidth();
    int height = getHeight();
    //System.out.println("width" + width);
    // System.out.println("height" + height);
    g.setColor(Color.yellow);
    g.fillRect(0, 0, width, height);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setStroke(new BasicStroke(3f));
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    //double x = 0.5 * width;
    //double y = 0.5 * height;
    double r = 0.75 * Math.min(x, y);



    double dx,dy;

    double t,l;
    l=Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
   // System.out.println("!!l!!"+l);
    t= l/V;
    //System.out.println("!!t!!"+t);
    g2d.setColor(Color.black);
    if(T<t) {
        dx = ((x2 - x1) / (Math.sqrt(Math.pow(x2 - x1, 2)) + Math.pow(y2 - y1, 2)));
        //System.out.println("!!dx!!" + dx);
        dy = ((y2 - y1) / (Math.sqrt(Math.pow(x2 - x1, 2)) + Math.pow(y2 - y1, 2)));
        //System.out.println("!!dy!!" + dy);
        x += x1 + dx * V * T;//+ dx * (V * T);
        //System.out.println("!!x!!" + x);
        //System.out.println("!!x1!!" + x1);
        y += y1 + dy * V * T;// + dy * (V * T);
        r =  Math.max(0.1 * r, 5);
       // System.out.println("!!y!!" + y);
        //System.out.println("!!y1!!" + x1);

    }


    if (x==x2 && y == y2 && T>t) {

     dx = ((x2 - x1) / (Math.sqrt(Math.pow(x2 - x1, 2)) + Math.pow(y2 - y1, 2)));

        dy = ((y2 - y1) / (Math.sqrt(Math.pow(x2 - x1, 2)) + Math.pow(y2 - y1, 2)));

        x -= x1 + dx * V * T;//+ dx * (V * T);

        y -= y1 + dy * V * T;// + dy * (V * T);
        r = Math.max(0.1 * r, 5);


    }

    g2d.fill(circle(x,y,r));

    //if (x == x2 && y == y2)
    // x = x1 -
}

public Shape circle(double x, double y, double R){

    return new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
}

@Override
public void actionPerformed(ActionEvent e) {
    switch (e.getActionCommand()) {
        case "stop": {
            timer.stop();
            break;
        }
        case "start": {
            timer.start();
            break;
        }
        case "apply": {
            float ax1, ay1, bx2, by2, cv;
            try {
                ax1 = Float.parseFloat(fx1.getText());
                ay1 = Float.parseFloat(fy1.getText());
                bx2 = Float.parseFloat(fx2.getText());
                by2 = Float.parseFloat(fy2.getText());
                cv = Float.parseFloat(fV.getText());
                x1 = ax1;
                y1 = ay1;
                x2 = bx2;
                y2 = by2;
                V = cv;
                repaint();
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(null, "Invalid input", "Error", 
JOptionPane.ERROR_MESSAGE);
            }
            break;
        }
        case "timer": {
            T += 0.6;
            System.out.println("!!T!!"+T);
            repaint();
            break;
   }
  }
 }
}

推荐答案

OP 定义了一个任务:

The OP defined a task:

蚂蚁在其居住地的一个地方移动(例如,[0;0]) 以速度 V 沿直线运动,然后返回他们的出生点以相同的速度.我有问题物体的移动.物体必须停在某个点并继续前进回到起点.

Ants move in one place in the region of their residence (for example, [0; 0]) in a straight line with a speed V, and then turn back to the point of their birth with the same speed.I have problems with the moving of objects. The object must stop at the certain point and go back to starting point.

然后他问?

我应该如何修复我的代码?

How should I fix my code?

为时已晚.需要调试和测试的代码行太多.

It's too late. There's too many lines of code to debug and test.

那么让我们重新开始吧.

So let's start over.

这是新代码的第一次迭代.

Here's the first iteration of the new code.

import javax.swing.SwingUtilities;

public class MovingAnts implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MovingAnts());
    }

    public MovingAnts() {

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

    }

}

我们可以通过运行该代码并观察到它没有异常终止来测试该代码.

We can test this code by running it and observing that it does not abend.

那么,让我们添加更多代码.我们知道我们将不得不定义一只或多只蚂蚁.所以,让我们创建一个 Ant 类.

So, let's add a bit more code. We know we're going to have to define one or more ants. So, let's create an Ant class.

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.SwingUtilities;

public class MovingAnts implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MovingAnts());
    }

    private List<Ant> ants;

    public MovingAnts() {
        ants = new ArrayList<>();

        Point origin = new Point(10, 10);
        Point destination = new Point(200, 300);
        Ant ant = new Ant(5.0d, origin, destination);
        ants.add(ant);
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

    }

    public class Ant {

        private final double velocity;

        private Point position;

        private final Point startPosition;
        private final Point endPosition;

        public Ant(double velocity, Point startPosition,
                Point endPosition) {
            this.velocity = velocity;
            this.startPosition = startPosition;
            this.endPosition = endPosition;
        }

        public double getVelocity() {
            return velocity;
        }

        public Point getPosition() {
            return position;
        }

        public void setPosition(Point position) {
            this.position = position;
        }

        public Point getStartPosition() {
            return startPosition;
        }

        public Point getEndPosition() {
            return endPosition;
        }

    }

}

我们已经定义了速度(速度)、起始位置和结束位置.根据任务描述,这些值不会改变,所以我们可以将它们标记为final并在构造函数中定义它们.

We've defined a velocity (speed), a starting position, and an ending position. According to the task description, these values don't change, so we can mark them final and define them in the constructor.

我们还定义了当前位置.当前位置将在稍后在绘图 JPanel 上绘制蚂蚁时很重要.

We've also defined a current position. The current position will be important later when it's time to draw the ant on a drawing JPanel.

随着我们开发更多代码,我们可能会向 Ant 类添加更多内容.但是现在,我们有一个类来保存蚂蚁的重要变量.

We will probably add more to the Ant class as we develop more code. But for now, we have a class that holds the important variables for a ant.

我们定义了一个蚂蚁(Ant 类的一个实例)并将蚂蚁保存在 MovingAnts 构造函数中的 List 中.我们可以稍后定义更多,但让我们从一只蚂蚁开始.

We defined an ant (one instance of the Ant class) and saved the ant in a List<Ant> in the MovingAnts constructor. We can define more later, but let's start with one ant.

现在,我们可以为蚂蚁创建JFrame并绘制JPanel.

Now, we can create the JFrame and drawing JPanel for the ants.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MovingAnts implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MovingAnts());
    }

    private Dimension drawingPanelSize;

    private DrawingPanel drawingPanel;

    private List<Ant> ants;

    public MovingAnts() {
        drawingPanelSize = new Dimension(400, 400);
        ants = new ArrayList<>();

        Point origin = new Point(10, 10);
        Point destination = new Point(200, 300);
        Ant ant = new Ant(5.0d, origin, destination);
        ants.add(ant);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Moving Ants");
        frame.setDefaultCloseOperation(
                JFrame.EXIT_ON_CLOSE);

        drawingPanel = new DrawingPanel(
                drawingPanelSize);
        frame.add(drawingPanel, BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        public DrawingPanel(Dimension drawingPanelSize) {
            this.setPreferredSize(drawingPanelSize);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
        }
    }

    public class Ant {

        private final double velocity;

        private Point position;

        private final Point startPosition;
        private final Point endPosition;

        public Ant(double velocity, Point startPosition,
                Point endPosition) {
            this.velocity = velocity;
            this.startPosition = startPosition;
            this.endPosition = endPosition;
        }

        public double getVelocity() {
            return velocity;
        }

        public Point getPosition() {
            return position;
        }

        public void setPosition(Point position) {
            this.position = position;
        }

        public Point getStartPosition() {
            return startPosition;
        }

        public Point getEndPosition() {
            return endPosition;
        }

    }

}

注意每个方法和类是如何简短而切中要点的.没有人可以在一个方法中阅读和理解数百行代码.

Notice how every method and class is short and to the point. No person can read and understand hundreds of lines of code in a single method.

我们一次添加了一小段代码,并通过运行应用程序来测试每一段代码.就他而言,我们有一个 GUI.我们也没有任何异常结束.GUI 和没有异常结束都很重要.

We've added a little bit of code at a time and tested each bit of code by running the application. At his point, we have a GUI. We also don't have any abends. Both the GUI and the lack of abends are important.

我们定义了绘图面板的大小.这个很重要.我们不在乎 JFrame 有多大.我们关心绘图 JPanel 有多大,所以我们可以将蚂蚁保持在绘图面板的范围内.

We defined the size of the drawing panel. This is important. We don't care how big the JFrame is. We care how big the drawing JPanel is, so we can keep the ants within the bounds of the drawing panel.

我们还没有在绘图面板的paintComponent方法中放入任何代码.在我们这样做之前,我们必须创建一个 Animation 类来更新蚂蚁的位置.

We haven't put any code in the paintComponent method of the drawing panel yet. Before we can do that, we have to create an Animation class that will update the position of the ants.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MovingAnts implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MovingAnts());
    }

    private Animation animation;

    private Dimension drawingPanelSize;

    private DrawingPanel drawingPanel;

    private List<Ant> ants;

    public MovingAnts() {
        drawingPanelSize = new Dimension(400, 400);
        ants = new ArrayList<>();

        Point origin = new Point(200, 200);
        Point destination = new Point(300, 350);
        Ant ant = new Ant(30.0d, origin, destination);
        ants.add(ant);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Moving Ants");
        frame.setDefaultCloseOperation(
                JFrame.EXIT_ON_CLOSE);

        drawingPanel = new DrawingPanel(
                drawingPanelSize);
        frame.add(drawingPanel, BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        animation = new Animation();
        new Thread(animation).start();
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        public DrawingPanel(Dimension drawingPanelSize) {
            this.setPreferredSize(drawingPanelSize);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());

            g.setColor(Color.BLACK);
            for (Ant ant : ants) {
                Point position = ant.getPosition();
                g.fillOval(position.x - 4,
                        position.y - 4, 8, 8);
            }
        }
    }

    public class Animation implements Runnable {

        private volatile boolean running;

        public Animation() {
            this.running = true;
        }

        @Override
        public void run() {
            int fps = 20;
            long delay = 1000L / fps;

            while (running) {
                calculateAntPosition(fps);
                updateDrawingPanel();
                sleep(delay);
            }

        }

        private void calculateAntPosition(int fps) {
            for (Ant ant : ants) {
                ant.calculatePosition(fps);
//              System.out.println(ant.getPosition());
            }
        }

        private void updateDrawingPanel() {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    drawingPanel.repaint();
                }
            });
        }

        private void sleep(long duration) {
            try {
                Thread.sleep(duration);
            } catch (InterruptedException e) {
                // Deliberately left empty
            }
        }

        public synchronized void setRunning(
                boolean running) {
            this.running = running;
        }

    }

    public class Ant {

        private boolean returning;

        private double totalDistance;
        private double traveledDistance;
        private double theta;

        private final double velocity;

        private Point position;

        private final Point startPosition;
        private final Point endPosition;

        public Ant(double velocity, Point startPosition,
                Point endPosition) {
            this.velocity = velocity;
            this.startPosition = startPosition;
            this.position = startPosition;
            this.endPosition = endPosition;
            this.returning = false;
            this.theta = calculateTheta();
            this.totalDistance = calculateTotalDistance();
            this.traveledDistance = 0d;
        }

        private double calculateTheta() {
            return Math.atan2((endPosition.y - startPosition.y),
                    endPosition.x - startPosition.x);
        }

        private double calculateTotalDistance() {
            double diffX = endPosition.x - startPosition.x;
            double diffY = endPosition.y - startPosition.y;
            return Math.sqrt((diffX * diffX) + (diffY * diffY));
        }

        public double getVelocity() {
            return velocity;
        }

        public Point getPosition() {
            return position;
        }

        public void calculatePosition(int fps) {
            double distance = velocity / fps;
            double angle = theta;

            if (returning) {
                angle += Math.PI;
            }

            int x = (int) Math.round(
                    position.x + distance * Math.cos(angle));
            int y = (int) Math.round(
                    position.y + distance * Math.sin(angle));

            traveledDistance += distance;
            if (traveledDistance > totalDistance) {
                returning = !returning;
                traveledDistance = 0d;
            }

            this.position = new Point(x, y);
        }

        public Point getStartPosition() {
            return startPosition;
        }

        public Point getEndPosition() {
            return endPosition;
        }

    }

}

我在这次迭代中添加了太多代码,但我们现在有一只蚂蚁在两点之间来回走动.

I added way too much code this iteration, but we now have an ant that walks back and forth between two points.

Animation 类是在 Thread 中运行的 Runnable.您可以使用 Swing Timer,但我更容易创建 Runnable.

The Animation class is a Runnable that runs in a Thread. You could use a Swing Timer, but it's easier for me to create the Runnable.

Ant 班长出了一些胸毛.所有的三角计算都可以在 Ant 类中找到.基本上,我用极坐标来计算蚂蚁的位置.

The Ant class grew some chest hair. All the trigonomic calculations can be found in the Ant class. Basically, I used polar coordinates to calculate the position of the ant.

绘图面板的paintComponent方法只是绘制蚂蚁.

The paintComponent method of the drawing panel simply draws the ants.

每个方法和类都很小,希望很容易理解.编写简短的方法.编写简短的课程.

Every method and class is small and hopefully, easy to understand. Write short methods. Write short classes.

希望此代码将为您扩展项目提供坚实的基础.

Hopefully, this code will provide a solid base for you to expand your project.

这篇关于物体的移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆