1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
% We want to demonstrate here the use of numerical analysis with
% Euler for real world problems.
%
% The problem is to shoot a canon ball with speed v and angle
% a. This can, of course, be computed exactly. But we restrict
% ourselfs to numerical solutions only.
%
% We fix the speed v=10 m/s and approximate gravity with g=10
% m/s^2.
>v=10; g=10;
% Now we plot a specific ballistic curve for a canon ball fired
% to 45 with the well known formulas for the curve neglecting
% friction.
%
% Time runs from 0 s to 2 s.
>t=0:0.1:2;
% The movement in x-direction (height) is cos(a)*v*t, but we must
% take care to compute 45 in radians first.
%
% The movement in y-direction is sin(a)*v*t minus the falling
% of g*t^2/2.
>xplot(cos(45)*v*t,sin(45)*v*t-g*t^2/2);
% We notice that we are not interested in the negative y-values
% and clip the plot to the postive quadrant.
%
% To copy the previous input, one can use the clipboard or recall
% the previous command with Alt-CursorUp.
>setplot(0,10,0,10); xplot(cos(45)*v*t,sin(45)*v*t-g*t^2/2);
% We now compute, when the ball has its heighest altitude. There
% is the funciton fmax, which computes the maximum of another
% function or expression in a given range.
>tmax=fmax("sin(45)*v*x-g*x^2/2",0,2)
0.707107
% How high is the maximal height?
>x=tmax; sin(45)*v*x-g*x^2/2
2.5
% To make things a little bit more comfortable, we introduce two
% functions computing the point (sx,sy) at time t.
%
% We take v and g fromt he global values, but add a as a parameter
% to these functions.
>function sx (t,a)
$global v;
$return cos(a)*v*t;
$endfunction
>function sy (t,a)
$global v,g;
$return sin(a)*v*t-g*t^2/2;
$endfunction
% This makes computing the maximal height more comfortable.
>a=45; sy(fmax("sy(x,a)",0,2),a)
2.5
% We wish to compare several angles. Thus we generate a vector
% of angles from 5 to 85 and generate all curves for all these
% angles simultanously.
%
% To do so, we need a as a column vektor and t as a row vector.
% Combining both yields a matrix, with a curve in each row for
% each angle.
>a=(5:5:85); a=a';
>xplot(sx(t,a),sy(t,a));
>setplot(0,10,0,10); xplot(sx(t,a),sy(t,a));
% This gave a nice picture.
%
% Lets us now compute the distance of the contact of the ball
% with the ground. We use the simplest of methods, the bijection
% method. Since 0 is already a solution of sy=0, we start a little
% bit off.
%
% We see the zero of vy. The additional parameter a (after the
% semicolon) is passed from bisect to sy.
%
% Note: Our function impact will only work for scalar a, not for
% vectors a.
>function distance (a)
$return sx(bisect("sy",0.00001,2;a),a);
$endfunction
% What happens, if we tage 50?
>distance(50)
9.84808
% We get about 9.85m far.
%
% Let us plot the impact distance with varying angles.
>a=(1:1:89);
% To compute the impact function to all angles, we use "map".
>xplot(deg(a),map("distance",a));
% We can also compute the optimal angle and its distance.
>amax=fmax("distance",1,89); deg(amax), distance(amax),
45
10
% Of course, it is easy to invert the function sx, i.e., compute
% the time t for the value x. We do not need to do that numerically.
%
% So we write a function that computes the height of the ball
% at distance x, if the angle is a.
>function height (x,a)
$global v;
$return sy(x/(cos(a)*v),a);
$endfunction
% Test ist with 45 from 0 to 10.
>fplot("height",0,10;45);
% We now want to get as high as possible in 5m distance. Again,
% we use fmax, but the argument x is now the second parameter
% to height, the angle.
>degprint(fmax("height(5,x)",1,89))
6326'5.82''
% We have to shoot about 63 (not 45 as expected).
%
% Now, we make a function that computes the angles that yields
% the maximal heights for given distances.
>function heighestangle (xx)
$global v;
$return fmax("height(xx,x)",1,89);
$endfunction
% Compute various maximal heights and plot them together with
% some shots.
>x=0.2:0.1:10; y=map("heighestangle",x);
>setplot(0,10,0,10); xplot(x,height(x,y));
>a=(5:5:85)'; hold on; xplot(sx(t,a),sy(t,a)); hold off;
% It the curve of maximal heights a parabola?
%
% Yes it is. To demosntrate, we compute the interpolation polynomial
% of second degree through the know values at -10, 0 and 10.
>d=interp([-10,0,10],[0,5,0]);
% Then we plot the polynomial over the current view in color 13.
% Indeed, we get the same curve.
>hold on; color(13); fplot("interpval([-10,0,10],d,x)",0,10); color(1); hold off;
% Next, we ask how to reach the point x=2, y=2. There seem to
% be two solutions. We get both by searching the angle below and
% the angle above the one with maximal height.
>a=heighestangle(2); degprint(a)
7841'24.24''
>a1=bisect("height(2,x)-2",0,a); degprint(a1)
5131'33.49''
>a2=bisect("height(2,x)-2",a,pi/2); degprint(a2)
8328'26.51''
% Let's plot both solutions to one plot.
>t=0:0.01:2;
>setplot(0,5,0,5); xplot(sx(t,a1),sy(t,a1));
>hold on; xplot(sx(t,a2),sy(t,a2)); hold off;
% Assume we shoot a ball in 80 and another one in 40. Can we
% hit the first with the secon in the air?
%
% For a start, we plot the two paths.
>fplot("height(x,80)",0,4); hold; fplot("height(x,40)",0,4); hold;
% Now we compute the point, where both paths meet and compute
% the time difference.
>xd=bisect("height(x,80)-height(x,40)",0.001,5)
3.07202
>xd/(v*cos(80))-xd/(v*cos(40))
1.36808
% Now we introduce friction. We assume the friction force is proprotional
% to c*v^2, where v is the speed.
%
% We need to solve a differential equation, using the "runge"
% function. The state x of the ball at any time t is 4-dimensional
% and contains two point coordinates and two speed coordinates.
% We need a function to compute x'=f(t,x).
%
% We set x=[sx,sy,sx',sy'].
>function f(t,x,c=0.005)
$global g;
$v=sqrt(x[3]*x[3]+x[4]*x[4]); rho=c*v;
$return [x[3],x[4],-rho*x[3],-g-rho*x[4]]
$endfunction
% We need to pass a vector of times t, where x will be computed.
% "runge" returns a matrix s, with one value for s in each column.
% We may plot the path of the ball from the first two rows of
% s.
>t=0:0.01:2; s=runge("f",t,[0,0,cos(45)*v,sin(45)*v]);
>setplot(0,10,0,10); xplot(s[1],s[2]);
>hold on; xplot(sx(t,45),sy(t,45)); hold off;
% Clearly, we do not get as far as before.
%
% Now we look at the speed over a larger time. The speed will
% tend to some value, where friction is equal to gravity.
>t=0:0.01:20; s=runge("f",t,[0,0,cos(45)*v,sin(45)*v]);
>xplot(t,sqrt(s[3]^2+s[4]^2));
% We wish to compute the angle of maximal width for this problem.
% It will no longer be exactly 45.
%
% First we define a function returning the height at time t.
>function height (t,a)
$global v;
$s=runge("f",[0,t],[0,0,cos(a)*v,sin(a)*v],20);
$return s[2,2];
$endfunction
>fplot("height",0,2;45);
% Then we seek the time when the height is 0 for any angle a,
% and return the width at that time.
>function width (a)
$t=bisect("height",0.001,2;a);
$global v;
$s=runge("f",[0,t],[0,0,cos(a)*v,sin(a)*v],20);
$return s[1,2];
$endfunction
>width(45)
9.62578
% Now we maximize the width over the angles.
%
% This computation takes some time (approx. 3 seconds on my modern
% Notebook)
%
% We find that the optimal angle is slightly less than 45.
>amax=fmax("width",30,60); degprint(amax)
4442'25.31''
>
>
|