Examples:
 

 

Example - Golf

* The "\" symbol has been used at the end of lines to indicate that the line was too long for the display and has been
wrapped to the line below in order to fit within the width of the web page. These lines would need to be joined in the normal
program editor.


I. Introduction

In the game of golf, where a ball is struck with a club with the intention of it landing in the correct place, a great deal depends on the aerodynamics of the ball in flight, and the bouncing characteristics of the ball on the ground. This program performs a simple analysis of the trajectory of a golf ball, and allows the observation of the relative effects of the factors that affect it.



II. Physics Involved

1) Presentation of the Problem

Consider a 2-dimensional plane, where a golfer has to hit a ball in such a way that it falls into the hole. The x-axis of the plane is the horizontal axis and the y-axis represents the altitude. The golfer can hit the ball in a certain direction, with certain strength, giving it a consequential initial velocity vector. The ball will then be subjected to the following forces:

  • Its weight, m.g , proportional to its mass, m , and gravity, g .
  • Air resistance, determined by considering the horizontal and vertical speeds of the ball, and and the speed of the wind, w , assumed to be a following wind for a positive w value.

2) Equations

2a) Movement of the Ball in the Air

The fundamental principle of dynamics says that the product of the weight and acceleration vector of a system (presently the ball) equals the sum of the force vectors applied to it, i.e. ma = mg + r k( v - w) 2 , where a is the acceleration vector of the ball, g is the gravity vector, r is the air density, k is the drag coefficient, v is the velocity of the ball relative to the ground and w is the wind, represented as a vector.

This is a differential equation since a = dv/dt . By solving this equation one can obtain the value of the ball's position vector, s, and so calculate the x and y position of the ball. Solving a differential equation such as this symbolically is not simple, but fortunately the FiniteElementArray object type will make it easy to solve numerically.


2b) Bounces

In an ideal case, when the ball would hit the ground it would rebound with the same speed, the y component just being reversed. In reality it's not like this; the ground absorbs a part of the kinetic energy of the ball, so its y speed component will decrease. The amount of decrease is determined by the bounce rate b r so that the new value of , will be given by . In the ideal case br would be 1, so no speed is lost; realistically b r is more likely to be around 0.5.


2c) Rolling of the Ball on the Ground

After a certain number of bounces the ball will simply roll on the ground, its horizontal velocity acting as before, but its vertical velocity being constant at zero. This is the least realistic part of the simulation, as it does not take into account friction with the ground, or any unevenness in the playing surface. However, since the rolling stage doesn't account for very much of the ball's total movement this doesn't affect the final result very much.



III. How the Program Works

1) Functionalities

This SBL program will allow the user to try to make the ball fall into the hole. Thus, he will be able to set the initial speed of the ball (by setting its horizontal and vertical values), but he will also be able to set many parameters:

  • The weight of the ball
  • The wind speed
  • The gravity value
  • The air density
  • The bounce rate of the ground


2) Initialisation: the GolfInit() Function

The main() procedure calls the GolfInit() function to perform the initialisation. After initialising the form, the GolfInit() function declares the following variables:

     GLOBAL xinit%%,yinit%%'initial position of the ball
     GLOBAL xh%%'position of the hole
     GLOBAL g%,p%,m%,w%,br%'gravity, air density, mass, wind and bounce rate
     GLOBAL tempx%,tempy%,t%'temporary position of the ball and time
     GLOBAL ballwidth%%,ballheight%%
     GLOBAL lastx%,lasty%,Counter%
     xinit%% = 100
     yinit%% = 4
     ballwidth%% = 15
     ballheight%% = 15
     xh%% = 750

Then it calls ControlsInit() , which sets the command buttons, text boxes and labels. But the most interesting part of the GolfInit() function is the initialisation of the finite element array:
     GLOBAL fea AS FiniteElmtArray
     fea.Name = "ballMvt"
     DIM fa AS FiniteElmtAttribute
     
     SET fa = fea.Add("x")'x-equation of the ball movement
     fa.SetFormula("-(p%/40)*(x(1)-w%)*sqr((x(1)-w%)^2 + y(1)^2)/m%",2)
     fa.Order = 2
     fa.AllowableErrorFactor = 0.01
     fa.AllowableErrorMin = 0.01
     
     SET fa = fea.Add("y")'y-equation of the ball movement
     fa.SetFormula("(-(p%/40)*y(1)*sqr((x(1)-w%)^2 + y(1)^2)/m%) - g%",2)
     fa.Order = 2
     fa.AllowableErrorFactor = 0.01
     fa.AllowableErrorMin = 0.01

We need two Finite Element Attributes, x and y . Their equations are the x- and y-axis projections of the equations explained above:

where the value of k is taken to be 1/40.


3) Movement of the Ball in the Air; Bounces

Each time the user clicks the Start button the RunProc() function is called. It first initialises the variables used:

SUB RunProc()
   ' Make sure the ball is returned to the starting point
   Golf.ball.move(xinit%% - 5,391 - yinit%%,ballwidth%%,ballheight%%)
   FORM 1

   lastx% = Golf.Ball.Left + INT (Golf.Ball.Width / 2)
'(ballwidth%% / 2) + x% - 5
lasty% = Golf.Ball.Top + INT (Golf.Ball.Height / 2)
'(ballheight%% / 2) + 391 - y%
fea.Stop() fea.x.SetInitialValue(xinit%%) fea.y.SetInitialValue(yinit%%) fea.x.SetInitialValue( VAL (Golf.sx0Box.Text),1) fea.y.SetInitialValue( VAL (Golf.sy0Box.Text),1) g% = VAL (Golf.GravityBox.Text) p% = VAL (Golf.DensityBox.Text) m% = VAL (Golf.MassBox.Text) w% = VAL (Golf.WindBox.Text) br% = VAL (Golf.BounceBox.Text) fea.AdvanceTo(0)

Then it draws the ball moving in the air and bouncing:

   t% = 0.01
   SET fc = Golf.Controls("ball")
   CALL Draw(fea.x(),fea.y())
   maxy% = 6
   'while the ball is bouncing:
   WHILE maxy% > 5 AND Golf.startbtn.Tag <> "" AND Golf.startbtn.Tag \
<> "stop" maxy% = 4 WHILE tempy% >= yinit%% AND Golf.startbtn.Tag <> "" AND \
Golf
.startbtn.Tag <> "stop" fea.AdvanceTo(t%) CALL Draw(fea.x(),fea.y()) IF tempy% > maxy% THEN maxy% = tempy% t% = t% + 0.02 Process() WEND 'initial values of the next bounce: tempsx% = fea.x(1)'save this value before we stop the fea tempsy% = - br% * fea.y(1)'the ball will be deadened fea.Stop()'so that we can restart it with the new values: fea.x.SetInitialValue(tempx%) fea.x.SetInitialValue(tempsx%,1) fea.y.SetInitialValue(tempsy%,1) t% = 0 tempy% = yinit%% WEND

The finite element array solves and integrates the differential equation; the x and y values are simply obtained by retrieving the value of fea.x() and fea.y() .

The Draw() function performs the drawing of the ball at the specified position.

When the ball hits the ground, it bounces: its x speed component does not change, while its y component is multiplied by -br as discussed in part I.

The ball begins to roll when it last bounced at an altitude lower than 5.


4) Rolling of the Ball

This time the y component of the speed is constant.

'now the ball will roll on the ground:
   w% = 0' Remove the influence of the wind now that we are rolling
   WHILE tdx% > 0.3 AND Golf.startbtn.Tag <> "" AND endloop%% = 0 \
AND
Golf.startbtn.Tag <> "stop" tdx% = 0 FOR i%% = 0 TO 99 dx% = tempx% fea.AdvanceTo(t%) CALL Draw(fea.x(),yinit%%)'this time y% is constant t% = t% + 0.03 dx% = tempx% - dx% tdx% = tdx% + ABS (dx%) IF ABS (tempx% - xh%%) < 1 THEN i%% = 99 endloop%% = - 1 END IF Process() IF Golf.startbtn.Tag = "" OR Golf.startbtn.Tag = "stop" THEN \
i
%% = 99 NEXT i%% WEND IF endloop%% THEN Golf.ball.move(xinit%% - 5,391 - yinit%%,ballwidth%%,ballheight%%) Golf.Refresh() REQUEST "Well done!","",2 ELSE IF Golf.startbtn.Tag = "stop" THEN ' Do nothing here ELSE 'IF Golf.startbtn.Tag <> "" THEN REQUEST "Missed!","",2 Golf.ball.move(xinit%% - 5,391 - yinit%%,ballwidth%%,ballheight%%) Golf.Refresh() END IF Golf.startbtn.Tag = "" END SUB

We check if the ball reaches the hole, and if it hasn't moved enough during a specific segment of time, we stop it.