Write a program to calculate the trajectory of a golf ball when it is putted by a player on the green, and display the result of the putt. The green is assumed to be a flat surface, either level or tilted upwards in the Y direction. The program calculations will include the effects of gravity, the slope of the green and the friction of the green on the rolling golf ball. All required formulas are given below.
We will assume the green is a flat 10m by 10m square, whose sides are the X and Y axes, with the origin in the bottom left corner (see figure 1). The green may be tilted so that the Y axis is at an angle relative to gravity, but the X axis is always horizontal (see figure 2). The Z axis is perpendicular to the green surface.
The hole is a circle with a radius of 54mm. The centre of the hole is at the centre of the square (position x = 5m and y = 5m). The aim of the putt is to hit the ball into the hole. The ball drops into the hole when it goes inside the hole circle. This occurs when the ball is within a distance of 54mm (0.054m) of the centre of the hole. Assuming the ball position is (x, y), an if state ment that checks for this is:
if (sqrt((x - 5) * (x - 5) + (y - 5) * (y - 5)) < 0.054)
Notice that calculations can be performed in the condition of an if statement, including function calls.
This theory is provided for background only. You may ignore the theory and simply use the theory results given below. This theory is based on the following paper (Penner, 2002): http://www.raypenner.com/golf-physics.pdf (accessed 11 August 2014)
The forces on the ball are the following.
Penner (2002) derives the following results that we will use. The x and y components of the ball acceleration are:
ax = -g.μ.cos().cos() / 1.4 and ay = -g.( μ.cos().sin() + sin() ) / 1.4
The constant 1.4 comes from assuming the ball is a uniform solid sphere. It is related to the mass, radius and moment of inertia of the ball.
The program calculates the position, velocity and acceleration of the ball as a function of time, in the two dimensions X and Y. It is assumed the ball is always on the green surface, either stationary or rolling, so z is always zero. The position is (x, y), the velocity is (vx, vy) and the acceleration is (ax, ay). The speed is s, where s = . The direction of motion is given by tan() = vy / vx.
Note that there are no simple formulas for x and y, because the acceleration is not constant due to the direction of motion and speed changing with time.
Therefore the program needs to calculate a numerical solution. This is a very common use of computers in engineering.
The program will calculate the values of t, x, y, vx, vy, ax, ay, s, at a series of times from time t = 0 when the ball is hit, in steps of time T until the ball goes in the hole, or stops moving, or rolls off the green. The smaller the value of T, the more accurate the result should be, but the longer the calculation will take.
Use Penner's formulas for the acceleration components ax and ay and the standard mechanics formulas for x, y, vx, vy.
x(t + T) = x(t) + vx(t).T + ½.ax.T2 y(t + T) = y(t) + vy(t).T + ½.ay.T2
vx(t + T) = vx(t) + ax.T vy(t + T) = vy(t) + ay.T
ax = -g.μ.cos().cos() / 1.4 ay = -g.( μ.cos().sin() + sin() ) / 1.4
The formulas for x, y, vx, vy are calculating these values at time t + T, using the previous values of x, y, vx, vy, ax and ay at time t. Perform the calculations in this order to get the correct results.
NOTE the minus signs in the formulas for ax and ay.
When the program is run, the user will enter the following values. Notice that the mathematical symbols have been changed into legal C/C++ variable names. You should use names that describe what the variable represents. However when complicated formulas are being calculated, we often use short names so the formulas are more readable.
Remember to convert the angles to radians for the trig formulas. The following formulas assume the angles sg and db in degrees have been converted to radians using variables sgr and dbr. As the ball rolls sgr will not change, but dbr will change (on a sloping green).
As each value is input, the program should check the value is valid. The program should loop on each variable, until a valid value is entered. See an example in the Hints section.
When the ball is hit (at time t = 0), the calculated initial values for position and velocity are:
x = xb, y = yb, vx = sb.cos(dbr), vy = sb.sin(dbr)
The initial acceleration is calculated using Penner's formulas for ax and ay.
Use a do-while loop because the number of times the loop will repeat is unknown. Use a Boolean variable to control the loop, because the conditions for ending the loop are too complicated for a condition in an if statement. For example, name the variable loop, set it to true initially, and set it to false inside the loop when it is appropriate to stop looping.
The program loop calculates the ball position, velocity and acceleration (in this order) using the formulas given earlier. The formulas assume that the accleration and velocity are constant over the time period T. This assumption is not exactly true, so the results of the calculation are not exactly correct. However if T is small, the assumption is approximately correct and the results will be reasonably accurate.
The time step T required for adequate accuracy is 0.001 second, but this produces too much output if the results of all calculations are displayed. Use an integer variable nt to count the time steps and calculate the time t as 0.001 * nt. Then display the calculated values whenever nt is a multiple of 100, that is whenever (nt % 100 == 0).
After each calculation at time t, your program needs to check if the ball has gone into the hole or off the green or has stopped rolling. Do this by checking if the x and y values are within 54mm of the centre of the hole, or if either x or y value is off the green (< 0 or > 10). If either of these has occured, the program can stop looping and display the result.
In this program, it can be difficult to determine when the ball has stopped moving, because the friction force due to N can cause the ball to slow down and stop, but friction cannot cause the ball to start rolling back in the reverse direction. Only the gravity force can reverse the direction of motion of the ball. However, because the calculations are done in time steps, it may appear that the friction force has caused the ball to reverse direction.
To detect that the ball has stopped, your program needs the current values of vx and vy, as well as their previous values. Suppose the previous values are in variables vxp and vyp.
Because there is no gravity force in the X direction, if vx changes sign then the ball has actually stopped moving in the X direction and your program should set vx to zero. From then on the ball will only move in the Y direction.
In the Y direction, if tan() > μ then the green is so steep the ball cannot stop and it will eventually roll off the green if it does not go in the hole.
However if tan() <= μ then the ball may stop, even on a sloping green, because the effect of gravity is less that the friction force. In this case, the ball stops rolling when the ball has stopped moving in the X direction and it appears to change direction in the Y direction.
To implement this logic do the following in your program:
if ((vx >= 0 and vxp <= 0) or (vx <= 0 and vxp >= 0)) then make vx = 0 because the ball has stopped rolling in the X direction.
if (vx ==0 and ((vy <= 0 and vyp >= 0) or (vy >= 0 and vyp <= 0)) and tan() <= μ) then make vy = 0 because the ball has stopped rolling in the Y direction and there is not enough gravity force to make it roll down the green.
As stated in the previous section, display the calculation results for every hundredth time step. Display the values of: t, x, y, vx, vy, ax, ay, s, d.
When the loop is complete, display the values of the same variables to show their final values.
See the Sample Program Output at the end of this specification.
The following pseudocode is one way you could organise the structure of your program. Notice that it follows the pattern of get input, perform calculations and display output. It also conforms with the marking scheme.
display the program title.
enter initial values for cf, sg, xb, yb, sb, db.
(use a do-while loop for each variable to ensure the value is valid.)
when all input is complete, display all the entered values.
calculate initial values for nt, t, x, y, vx, vy, ax, ay, s, d.
display the output table title line.
display the values of t, x, y, vx, vy, ax, ay, s, d at time t = 0.
set loop to true, set vxp to vx, and set vyp to vy.
do
calculate the next values of nt, t, x, y, vx, vy, ax, ay, s, d.
if the ball is in the hole
set loop to false, and set result string to an appropriate message
if the ball is off the green
set loop to false, and set result string to an appropriate message
if the ball has stopped moving
set loop to false, and set result string to an appropriate message
if nt is a multiple of 100
display the values of t, x, y, vx, vy, ax, ay, s, d.
set vxp to vx, and set vyp to vy.
while loop is true.
display the values of t, x, y, vx, vy, ax, ay, s, d.
display the result string message.
display end of program
Remember the trig functions need angles in radians, so the angles entered in degrees need to be converted to radians. The value of is named M_PI in the cmath header file. To access this value, you need to define _USE_MATH_DEFINES before your include statements, as follows:
#define _USE_MATH_DEFINES
#include < iostream >
#include < cmath >
Use do-while loops to check that the input data is valid, and repeat the input of each data item until a valid value is entered. For example:
// input ball speed
do
{
cout << “Enter ball speed:”;
cin >> sb;
} while (sb <= 0 || sb > 5);
Use a do-while loop to repeat the program calculations, because the number of loop repetitions is unknown, and the calculations need to be performed at least once.