17inline double beta(
double k,
double st,
double smax,
double gamma = 4.25756) {
19 return sqrt(sqrt((gamma*gamma*smax*smax - k*k*st*st*st*st)*(gamma*gamma*smax*smax - k*k*st*st*st*st)));
22inline double RungeKutte_riv(
double ds,
double st,
double k[],
double smax,
double gamma = 4.25756) {
24 double k1 = ds * (1/st) * beta(k[0], st, smax, gamma);
25 double k2 = ds * 1 / (st + k1/2) * beta(k[1], st + k1/2, smax, gamma);
26 double k3 = ds * 1 / (st + k2/2) * beta(k[1], st + k2/2, smax, gamma);
27 double k4 = ds * 1 / (st + k3/2) * beta(k[2], st + k3/2, smax, gamma);
28 return (k1/6 + k2/3 + k3/3 + k4/6);
31inline void minTimeGradientRIV(
double* x,
double* y,
double* z,
int Lp,
double g0,
double gfin,
double gmax,
double smax,
32 double dt,
double*& gx,
double*& gy,
double*& gz,
33 int &l_t,
double ds = -1,
double gamma = 4.25756) {
59 double *p =
new double[Lp];
62 for (i = 0; i < Lp; ++i)
68 double *c1x =
new double[Lp];
69 double *c2x =
new double[Lp];
70 double *c3x =
new double[Lp];
71 double *c1y =
new double[Lp];
72 double *c2y =
new double[Lp];
73 double *c3y =
new double[Lp];
74 double *c1z =
new double[Lp];
75 double *c2z =
new double[Lp];
76 double *c3z =
new double[Lp];
78 spline(Lp, 0, 0, 1, 1, p, x, c1x, c2x, c3x, &iflag);
79 spline(Lp, 0, 0, 1, 1, p, y, c1y, c2y, c3y, &iflag);
80 spline(Lp, 0, 0, 1, 1, p, z, c1z, c2z, c3z, &iflag);
83 int num_evals = (int) floor((Lp-1) / dp)+ 1;
88 double *s_of_p =
new double[num_evals];
91 double *sop_num =
new double[num_evals];
94 double Cp_abs_pre = 0.;
95 for (i = 0; i < num_evals; ++i) {
96 toeval = (double) i * dp;
97 double Cpx = deriv(Lp, toeval, p, c1x, c2x, c3x, &last);
98 double Cpy = deriv(Lp, toeval, p, c1y, c2y, c3y, &last);
99 double Cpz = deriv(Lp, toeval, p, c1z, c2z, c3z, &last);
101 double Cp_abs = sqrt(Cpx*Cpx + Cpy*Cpy + Cpz*Cpz);
102 sofar += (Cp_abs + Cp_abs_pre)/2;
103 s_of_p[i] = dp * sofar;
110 double L = s_of_p[num_evals-1];
113 double stt0 = gamma*smax;
114 double st0 = (stt0*dt)/2;
119 ds = fabs(ds) * s0/1.5;
122 int length_of_s = (int) floor(L/ds);
123 int half_ls = (int) floor(L/(ds/2));
125 double *s =
new double[length_of_s];
126 double *sta =
new double[length_of_s];
127 double *stb =
new double[length_of_s];
129 for (i = 0; i<length_of_s; i++) {
136 double *a1x =
new double[num_evals];
137 double *a2x =
new double[num_evals];
138 double *a3x =
new double[num_evals];
140 spline(num_evals, 0, 0, 1, 1, s_of_p, sop_num, a1x, a2x, a3x, &iflag);
142 double *s_half =
new double[half_ls];
143 double *p_of_s_half =
new double[half_ls];
145 for (i=0; i < half_ls; ++i) {
146 s_half[i] = (double)i*(ds/2);
147 p_of_s_half[i] = seval(num_evals, s_half[i], s_of_p, sop_num, a1x, a2x, a3x, &last);
150 delete[] a1x;
delete[] a2x;
delete[] a3x;
151 delete[] s_of_p;
delete[] sop_num;
154 double *Cspx =
new double[length_of_s];
155 double *Cspy =
new double[length_of_s];
156 double *Cspz =
new double[length_of_s];
158 double *p_of_s =
new double[length_of_s];
160 for (i=0; i<length_of_s; ++i) {
161 p_of_s[i] = p_of_s_half[2*i];
162 Cspx[i] = seval(Lp, p_of_s[i], p, x, c1x, c2x, c3x, &last);
163 Cspy[i] = seval(Lp, p_of_s[i], p, y, c1y, c2y, c3y, &last);
164 Cspz[i] = seval(Lp, p_of_s[i], p, z, c1z, c2z, c3z, &last);
166 delete[] p_of_s_half;
169 double *Csp1x =
new double[length_of_s];
170 double *Csp2x =
new double[length_of_s];
171 double *Csp3x =
new double[length_of_s];
172 double *Csp1y =
new double[length_of_s];
173 double *Csp2y =
new double[length_of_s];
174 double *Csp3y =
new double[length_of_s];
175 double *Csp1z =
new double[length_of_s];
176 double *Csp2z =
new double[length_of_s];
177 double *Csp3z =
new double[length_of_s];
178 spline(length_of_s, 0, 0, 1, 1, s, Cspx, Csp1x, Csp2x, Csp3x, &iflag);
179 spline(length_of_s, 0, 0, 1, 1, s, Cspy, Csp1y, Csp2y, Csp3y, &iflag);
180 spline(length_of_s, 0, 0, 1, 1, s, Cspz, Csp1z, Csp2z, Csp3z, &iflag);
182 int size_k = half_ls+2;
183 double *k =
new double[size_k];
184 for (i=0; i < half_ls; ++i) {
185 double kx = deriv2(length_of_s, s_half[i], s, Csp1x, Csp2x, Csp3x, &last);
186 double ky = deriv2(length_of_s, s_half[i], s, Csp1y, Csp2y, Csp3y, &last);
187 double kz = deriv2(length_of_s, s_half[i], s, Csp1z, Csp2z, Csp3z, &last);
188 k[i] = sqrt(kx*kx + ky*ky + kz*kz);
190 k[size_k-2] = k[size_k-3];
191 k[size_k-1] = k[size_k-3];
194 delete[] Cspx;
delete[] Cspy;
delete[] Cspz;
195 delete[] Csp1x;
delete[] Csp1y;
delete[] Csp1z;
196 delete[] Csp2x;
delete[] Csp2y;
delete[] Csp2z;
197 delete[] Csp3x;
delete[] Csp3y;
delete[] Csp3z;
200 double *sdot =
new double[half_ls];
205 double gammagmax = gamma*gmax;
206 for (i=0; i< half_ls; ++i) {
207 double sdot2 = sqrt((gamma*smax) / (fabs(k[i]+(DBL_EPSILON))));
208 if (gammagmax < sdot2)
214 double g0gamma = g0*gamma + st0;
215 if (g0gamma < gammagmax)
222 for (i=1; i<length_of_s; ++i) {
228 double dstds = RungeKutte_riv(ds, sta[i-1], k_rk, smax, gamma);
229 double tmpst = sta[i-1] + dstds;
231 if (sdot[2*i+1] < tmpst)
232 sta[i] = sdot[2*i+1];
242 stb[length_of_s-1] = sta[length_of_s - 1];
245 if (gfin * gamma > st0)
251 stb[length_of_s-1] = gammagmax;
253 stb[length_of_s-1] = max;
256 for (i=length_of_s-2; i>-1; --i) {
262 double dstds = RungeKutte_riv(ds, stb[i+1], k_rk, smax, gamma);
263 double tmpst = stb[i+1] + dstds;
265 if (sdot[2*i] < tmpst)
281 double st_ds_i_pre = ds*(1/st_of_s);
283 double *t_of_s =
new double[length_of_s];
285 for (i=1; i < length_of_s; ++i) {
291 double st_ds_i = ds*(1/st_of_s);
293 t_of_s[i] = t_of_s[i-1] + (st_ds_i+ st_ds_i_pre)/2;
295 st_ds_i_pre = st_ds_i;
297 delete[] sta;
delete[] stb;
299 l_t = (int) floor(t_of_s[length_of_s-1]/dt);
303 double *t1x =
new double[length_of_s];
304 double *t2x =
new double[length_of_s];
305 double *t3x =
new double[length_of_s];
307 spline(length_of_s, 0, 0, 1, 1, t_of_s, s, t1x, t2x, t3x, &iflag);
311 double *p1x =
new double[length_of_s];
312 double *p2x =
new double[length_of_s];
313 double *p3x =
new double[length_of_s];
315 spline(length_of_s, 0, 0, 1, 1, s, p_of_s, p1x, p2x, p3x, &iflag);
317 double *p_of_t =
new double[l_t];
319 for (i=0; i < l_t; ++i) {
320 double s_of_t = seval(length_of_s, i*dt, t_of_s, s, t1x, t2x, t3x, &last);
321 p_of_t[i] = seval(length_of_s, s_of_t, s, p_of_s, p1x, p2x, p3x, &last);
324 delete[] t1x;
delete[] t2x;
delete[] t3x;
326 delete[] s;
delete[] p_of_s;
327 delete[] p1x;
delete[] p2x;
delete[] p3x;
330 double *Cx =
new double[l_t];
331 double *Cy =
new double[l_t];
332 double *Cz =
new double[l_t];
334 for (i=0; i<l_t; i++) {
335 Cx[i] = seval(Lp, p_of_t[i], p, x, c1x, c2x, c3x, &last);
336 Cy[i] = seval(Lp, p_of_t[i], p, y, c1y, c2y, c3y, &last);
337 Cz[i] = seval(Lp, p_of_t[i], p, z, c1z, c2z, c3z, &last);
339 delete[] p_of_t;
delete[] p;
340 delete[] c1x;
delete[] c1y;
delete[] c1z;
341 delete[] c2x;
delete[] c2y;
delete[] c2z;
342 delete[] c3x;
delete[] c3y;
delete[] c3z;
345 gx =
new double[l_t];
346 gy =
new double[l_t];
347 gz =
new double[l_t];
349 for (i=0; i< l_t - 1; ++i) {
350 gx[i] = (Cx[i+1] - Cx[i]) / (gamma * dt);
351 gy[i] = (Cy[i+1] - Cy[i]) / (gamma * dt);
352 gz[i] = (Cz[i+1] - Cz[i]) / (gamma * dt);
354 delete[] Cx;
delete[] Cy;
delete[] Cz;
356 gx[l_t-1] = 2*gx[l_t-2] - gx[l_t-3];
357 gy[l_t-1] = 2*gy[l_t-2] - gy[l_t-3];
358 gz[l_t-1] = 2*gz[l_t-2] - gz[l_t-3];
362inline void calcTrajectory(
double *gx,
double *gy,
double *gz,
int l_t,
double dt,
double*& kx,
double*& ky,
double*& kz,
double gamma = 4.25756) {
364 kx =
new double[l_t];
365 ky =
new double[l_t];
366 kz =
new double[l_t];
376 for (
int i=1; i < l_t; ++i) {
377 sofarx += (gx[i] + gx[i-1]) / 2;
378 sofary += (gy[i] + gy[i-1]) / 2;
379 sofarz += (gz[i] + gz[i-1]) / 2;
381 kx[i] = sofarx * dt * gamma;
382 ky[i] = sofary * dt * gamma;
383 kz[i] = sofarz * dt * gamma;