Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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;
   }
  }
 }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
125 views
Welcome To Ask or Share your Answers For Others

1 Answer

The OP defined a 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.

And then he asked?

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.

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;
        }

    }

}

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.

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.

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.

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.

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.

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.

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.

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;

            

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...