Нужно нарисовать метательное движение броска мяча

Поэтому я пишу код, который позволяет пользователю бросать воображаемый объект под начальным углом и скоростью, чтобы увидеть, могут ли они приблизиться к удару по мячу (который позиционируется на основе пользовательского ввода).

Однако у меня возникают проблемы при рисовании кривой введенного пользователем угла и скорости воображаемого объекта.

Я использовал математическую формулу для расчета общего времени и диапазона указанного объекта. То есть:

= 02sin⁡ (2/180) = 20sin⁡ (/ 180)

Я уже пытался попытаться поместить диапазон и общее время в дугу и построить его таким образом. Но это не сработало.

Вот код:

import java.awt.AWTEvent;
import java.awt.*;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.util.Scanner;
import java.awt.geom.QuadCurve2D;
public class BallGame extends JFrame {

    public static void main (String[]args)
    {
        Scanner cool= new Scanner(System.in);
        double angle, speed, range, totalTime;

        {
            JFrame frame = new JFrame (" Throwing Ball");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(700,700);
        }

        {
            System.out.println("Please enter the location of the ball (0 < X < 1)");
            StdDraw.setPenRadius(0.06);
            StdDraw.setPenColor(StdDraw.BLUE);
            double x, y;
            y = 0;
            x = cool.nextDouble();
            StdDraw.point(x, y);
        }

        System.out.println("Please enter an angle of your choosing:");
        angle = cool.nextDouble();

        System.out.println("Please enter the speed at wish you which to throw the ball");
        speed = cool.nextDouble();

        double g;
        g = 9.8;
        range = Math.pow(speed, 2) * Math.sin(2 * angle * (Math.PI / 180) / g);
        totalTime = (2 * speed * Math.sin(angle * Math.PI / 180)) / g;

1 ответ

Для построения кривой вам необходимо рассчитать горизонтальное (x) и вертикальное (y) положение как функцию времени, начальной точки, начальной скорости и угла. Другими словами, рассчитайте горизонтальное расстояние и вертикальное расстояние. Уравнения хорошо известны и широко доступны.

Вы используете эти уравнения для многократного вычисления x,y, а затем перерисовываете.
Смотрите следующую демонстрацию. Не комментарии:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class BalisticCurve extends JFrame {

    private static final double G = 9.8; //positive because Y axis is positive going down
    private int animationSpeed = 5; //millis. The smaller the faster
    private static int size = 900, ballDiameter = 10;
    private double startX, startY, ballX, ballY;
    private double xSpeed, ySpeed, lastPointX, lastPointY;
    private double time, deltaTime = 0.01 ; //in seconds
    private List<Point2D> curvePoints= new ArrayList<>();
    private Timer timer;

    BalisticCurve(){

        super("Balistic Curve");
        DrawBoard board  = new DrawBoard();
        add(board, BorderLayout.CENTER);

        ballX= lastPointX = startX = 50;
        ballY = lastPointY = startY = size - 100;
        getUserInput();

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        timer = new Timer(animationSpeed, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {

                board.moveBall();
                board.repaint();
                if(! inBounds()) {
                    timer.stop();
                }
            }
        });
        timer.start();
    }

    private void getUserInput() {

        double angle = 45;//todo replace with user input + verification
        double speed = 100;
        xSpeed = speed * Math.cos(angle * (Math.PI / 180));
        ySpeed = speed * Math.sin(angle * (Math.PI / 180));
    }

    private boolean inBounds() {

        //ignore if ball exceeds height
        if((ballX < 0) || (ballX > (getWidth()))
                || ( ballY  > (getHeight() - ballDiameter) ) ) {
            return false;
        }

        return true;
    }

    class DrawBoard extends JPanel {

        public DrawBoard() {
            setPreferredSize(new Dimension(size, size));
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);

            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.RED);
            g2d.fillOval((int)ballX,(int)ballY,ballDiameter,ballDiameter);

            if((Math.abs(lastPointX - ballX)>=1) && (Math.abs(lastPointY - ballY)>=1) ) {
                curvePoints.add(new Point2D.Double(ballX, ballY));
                lastPointX = ballX; lastPointY = ballY;
            }

            drawCurve(g2d);
        }

        private void drawCurve(Graphics2D g2d) {

            g2d.setColor(Color.BLUE);
            for(int i=0; i < (curvePoints.size()-1); i++) {

                Point2D from = curvePoints.get(i);
                Point2D to = curvePoints.get(i+1);
                g2d.drawLine((int)from.getX(),(int)from.getY(), (int)to.getX(), (int)to.getY());
            }
        }

        private void moveBall() {

            ballX = startX + (xSpeed * time);
            ballY = startY - ((ySpeed *time)-(0.5 *G * Math.pow(time, 2))) ;
            time += deltaTime;
        }
    }

    public static void main(String[] args) {

        new BalisticCurve();
    }
}

Не стесняйтесь спрашивать, что недостаточно ясно.

Другие вопросы по тегам