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

Categories

0 votes
552 views
in Technique[技术] by (71.8m points)

java - Need to draw projectile motion of a thrown ball

So I'm writing a code that allows a user to throw an imaginary object at an initial angle and speed to see if they can come close to hitting a ball (that is positioned based on user input).

However, I'm having trouble drawing the curve of the users inputted angle and speed of the imaginary object.

I've used a mathematical formula to calculate the total time and range of said object. That is:

??????????= ??02sin?(2????/180)?? ?????????? ????????= 2??0sin?(????/180)??

I've already tried attempting to put range and total time into an arc and plotting it that way. But that didn't seem to work.

Here's the code:

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

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

1 Answer

0 votes
by (71.8m points)

For drawing a curve you need to calculate horizontal (x) and vertical (y) position, as a function of time, start point, start speed and angle. In other words, calculate the horizontal distance, and vertical distance. The equations are well known and widely available.

You use these equations to repeatedly calculate x,y and then repaint.
See the following demonstration. Not the comments :

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

enter image description here

Don't hesitate to ask what is not clear enough.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...