1 #include "a/trajbell.h"
4 #if A_PREREQ_GNUC(3, 0) || __has_warning("-Wfloat-equal")
5 #pragma GCC diagnostic ignored "-Wfloat-equal"
6 #endif /* -Wfloat-equal */
8 a_float
a_trajbell_gen(a_trajbell
*ctx
, a_float jm
, a_float am
, a_float vm
,
9 a_float p0
, a_float p1
, a_float v0
, a_float v1
)
11 a_float p
, ac
, tj
, _2tj
, _2v0
, _2v1
, _tmp
, temp
, v0pv1
, _2v02pv12
;
12 if (jm
< 0) { jm
= -jm
; }
13 if (am
< 0) { am
= -am
; }
14 if (vm
< 0) { vm
= -vm
; }
15 v0
= A_SAT(v0
, -vm
, +vm
);
16 v1
= A_SAT(v1
, -vm
, +vm
);
34 ctx
->taj
= a_float_sqrt(_2v0
/ jm
);
35 ctx
->ta
= 2 * ctx
->taj
;
36 ctx
->am
= +jm
* ctx
->taj
;
41 ctx
->ta
= ctx
->taj
+ _2v0
/ am
;
47 ctx
->tdj
= a_float_sqrt(_2v1
/ jm
);
48 ctx
->td
= 2 * ctx
->tdj
;
49 ctx
->dm
= -jm
* ctx
->tdj
;
54 ctx
->td
= ctx
->tdj
+ _2v1
/ am
;
58 ctx
->tv
= p
/ vm
- A_FLOAT_C(0.5) * ctx
->ta
* (1 + v0
/ vm
) - A_FLOAT_C(0.5) * ctx
->td
* (1 + v1
/ vm
);
59 if (ctx
->tv
> 0) { goto out
; }
65 ctx
->dm
= ac
* A_FLOAT_C(0.0625);
66 _2v02pv12
= 2 * (v0
* v0
+ v1
* v1
);
73 temp
= _tmp
* _tmp
+ _2v02pv12
+ (4 * p
- _2tj
* v0pv1
) * am
;
74 _tmp
+= a_float_sqrt(temp
);
76 ctx
->ta
= (_tmp
- _2v0
) / temp
;
79 if (am
== ctx
->am
|| ac
< ctx
->dm
)
83 ctx
->td
= 2 * p
/ v0pv1
;
85 temp
= jm
* (_tmp
* p
+ (v1
- v0
) * v0pv1
* v0pv1
);
86 if (temp
< 0) { goto fail
; }
87 ctx
->tdj
= (_tmp
- a_float_sqrt(temp
)) / (jm
* v0pv1
);
89 ctx
->dm
= -jm
* ctx
->tdj
;
97 ctx
->td
= (_tmp
- _2v1
) / temp
;
100 if (am
== ctx
->am
|| ac
< ctx
->dm
)
104 ctx
->ta
= 2 * p
/ v0pv1
;
106 temp
= jm
* (_tmp
* p
+ (v0
- v1
) * v0pv1
* v0pv1
);
107 if (temp
< 0) { goto fail
; }
108 ctx
->taj
= (_tmp
- a_float_sqrt(temp
)) / (jm
* v0pv1
);
109 ctx
->am
= +jm
* ctx
->taj
;
111 ctx
->vm
= v0
+ ctx
->am
* (ctx
->ta
- ctx
->taj
);
114 ac
*= A_FLOAT_C(0.5);
118 if (ctx
->ta
>= _2tj
&& ctx
->td
>= _2tj
)
120 if (am
== ctx
->am
|| ac
< ctx
->dm
)
124 ctx
->vm
= v0
+ ctx
->am
* (ctx
->ta
- tj
);
127 ac
*= A_FLOAT_C(0.5);
131 ac
*= A_FLOAT_C(0.5);
133 } while (ac
> A_FLOAT_EPSILON
);
138 ctx
->t
= ctx
->ta
+ ctx
->tv
+ ctx
->td
;
142 a_float
a_trajbell_pos(a_trajbell
const *ctx
, a_float dt
)
145 a_float p0
= ctx
->p0
;
146 a_float p1
= ctx
->p1
;
147 a_float v0
= ctx
->v0
;
148 a_float v1
= ctx
->v1
;
149 a_bool
const rev
= ctx
->p0
> ctx
->p1
;
161 if (dt
<= 0) { return ctx
->p0
; }
162 out
= p0
+ v0
* dt
+ ctx
->jm
* dt
* dt
* dt
/ 6;
165 if (dt
< ctx
->ta
- ctx
->taj
)
167 out
= p0
+ v0
* dt
+ ctx
->am
* (3 * dt
* dt
- 3 * dt
* ctx
->taj
+ ctx
->taj
* ctx
->taj
) / 6;
171 out
= p0
+ A_FLOAT_C(0.5) * (ctx
->vm
+ v0
) * ctx
->ta
- ctx
->vm
* dt
+ ctx
->jm
* dt
* dt
* dt
/ 6;
174 if (dt
< ctx
->t
- ctx
->td
+ ctx
->tdj
)
176 if (dt
< ctx
->ta
+ ctx
->tv
)
178 out
= p0
+ A_FLOAT_C(0.5) * (ctx
->vm
+ v0
) * ctx
->ta
+ ctx
->vm
* (dt
- ctx
->ta
);
181 dt
-= ctx
->t
- ctx
->td
;
182 out
= p1
- A_FLOAT_C(0.5) * (ctx
->vm
+ v1
) * ctx
->td
+ ctx
->vm
* dt
- ctx
->jm
* dt
* dt
* dt
/ 6;
187 if (dt
< ctx
->t
- ctx
->tdj
)
189 dt
-= ctx
->t
- ctx
->td
;
190 out
= p1
- A_FLOAT_C(0.5) * (ctx
->vm
+ v1
) * ctx
->td
+ ctx
->vm
* dt
+
191 ctx
->dm
* (3 * dt
* dt
- 3 * dt
* ctx
->tdj
+ ctx
->tdj
* ctx
->tdj
) / 6;
195 out
= p1
- v1
* dt
- ctx
->jm
* dt
* dt
* dt
/ 6;
200 return rev
? -out
: out
;
203 a_float
a_trajbell_vel(a_trajbell
const *ctx
, a_float dt
)
206 a_float v0
= ctx
->v0
;
207 a_float v1
= ctx
->v1
;
208 a_bool
const rev
= ctx
->p0
> ctx
->p1
;
218 if (dt
<= 0) { return ctx
->v0
; }
219 out
= v0
+ A_FLOAT_C(0.5) * ctx
->jm
* dt
* dt
;
222 if (dt
< ctx
->ta
- ctx
->taj
)
224 out
= v0
+ ctx
->am
* (dt
- A_FLOAT_C(0.5) * ctx
->taj
);
228 out
= ctx
->vm
- A_FLOAT_C(0.5) * ctx
->jm
* dt
* dt
;
231 if (dt
< ctx
->t
- ctx
->td
+ ctx
->tdj
)
233 if (dt
< ctx
->ta
+ ctx
->tv
)
238 dt
-= ctx
->t
- ctx
->td
;
239 out
= ctx
->vm
- A_FLOAT_C(0.5) * ctx
->jm
* dt
* dt
;
244 if (dt
< ctx
->t
- ctx
->tdj
)
246 out
= ctx
->vm
+ ctx
->dm
* (dt
- ctx
->t
+ ctx
->td
- A_FLOAT_C(0.5) * ctx
->tdj
);
250 out
= v1
+ A_FLOAT_C(0.5) * ctx
->jm
* dt
* dt
;
255 return rev
? -out
: out
;
258 a_float
a_trajbell_acc(a_trajbell
const *ctx
, a_float dt
)
265 if (dt
< ctx
->ta
- ctx
->taj
)
270 out
= ctx
->jm
* (ctx
->ta
- dt
);
279 else if (dt
< ctx
->t
- ctx
->td
+ ctx
->tdj
)
281 if (dt
>= ctx
->ta
+ ctx
->tv
)
283 out
= -ctx
->jm
* (dt
- ctx
->t
+ ctx
->td
);
287 else if (dt
< ctx
->t
)
289 if (dt
< ctx
->t
- ctx
->tdj
)
294 out
= -ctx
->jm
* (ctx
->t
- dt
);
299 if (ctx
->p0
> ctx
->p1
)
306 a_float
a_trajbell_jer(a_trajbell
const *ctx
, a_float dt
)
311 if (dt
>= ctx
->ta
- ctx
->taj
)
316 if (dt
< ctx
->taj
&& dt
>= 0)
322 else if (dt
< ctx
->t
- ctx
->td
+ ctx
->tdj
)
324 if (dt
>= ctx
->ta
+ ctx
->tv
)
330 else if (dt
<= ctx
->t
)
332 if (dt
>= ctx
->t
- ctx
->tdj
)
340 if (ctx
->p0
> ctx
->p1
)