File: ballistics.en

package info (click to toggle)
euler 1.61.0-12
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 5,164 kB
  • sloc: ansic: 24,761; sh: 8,314; makefile: 141; cpp: 47; php: 1
file content (208 lines) | stat: -rw-r--r-- 7,567 bytes parent folder | download | duplicates (7)
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''
>
>