1 #include "a/traptraj.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_traptraj_gen(a_traptraj
*ctx
, a_float qm
, a_float vm
, a_float ac
, a_float de
, a_float vs
, a_float ve
)
10 a_float vs2
, ve2
, vc2
;
11 a_float
const _2q
= 2 * qm
;
12 a_bool
const reversed
= qm
< 0;
13 if (vm
< 0) { vm
= -vm
; }
14 if (vs
> vm
) { vs
= vm
; }
15 else if (vs
< -vm
) { vs
= -vm
; }
16 if (ve
> vm
) { ve
= vm
; }
17 else if (ve
< -vm
) { ve
= -vm
; }
18 if (ac
== de
) { return 0; }
25 vc2
= (ve2
* ac
- vs2
* de
- _2q
* ac
* de
) / (ac
- de
);
26 if (vc2
<= 0) { return 0; }
27 if (vc2
> vm
* vm
) /* acceleration, constant velocity, deceleration */
29 ctx
->vc
= reversed
? -vm
: vm
;
30 ctx
->t1
= (ctx
->vc
- vs
) / ac
;
31 ctx
->t
= (ve
- ctx
->vc
) / de
;
32 ctx
->q1
= ctx
->vs
* ctx
->t1
+ A_FLOAT_C(0.5) * ac
* ctx
->t1
* ctx
->t1
;
33 ctx
->q
= ctx
->vc
* ctx
->t
+ A_FLOAT_C(0.5) * de
* ctx
->t
* ctx
->t
;
34 ctx
->q2
= qm
- ctx
->q
;
35 ctx
->t2
= (ctx
->q2
- ctx
->q1
) / ctx
->vc
;
40 else if (vc2
> vs2
&& vc2
<= ve2
) /* acceleration */
43 if (ve2
< 0) { return 0; }
44 ctx
->ve
= a_float_sqrt(ve2
);
45 if (reversed
) { ctx
->ve
= -ctx
->ve
; }
47 ctx
->t1
= (ctx
->ve
- vs
) / ac
;
50 ctx
->q1
= ctx
->vs
* ctx
->t1
+ A_FLOAT_C(0.5) * ac
* ctx
->t1
* ctx
->t1
;
54 else if (vc2
<= vs2
&& vc2
> ve2
) /* deceleration */
57 if (ve2
< 0) { return 0; }
58 ctx
->ve
= a_float_sqrt(ve2
);
59 if (reversed
) { ctx
->ve
= -ctx
->ve
; }
63 ctx
->t
= (ctx
->ve
- vs
) / de
;
66 ctx
->q
= ctx
->vc
* ctx
->t
+ A_FLOAT_C(0.5) * de
* ctx
->t
* ctx
->t
;
68 else /* acceleration, deceleration */
70 ctx
->vc
= a_float_sqrt(vc2
);
71 if (reversed
) { ctx
->vc
= -ctx
->vc
; }
72 ctx
->t1
= (ctx
->vc
- vs
) / ac
;
74 ctx
->t
= (ve
- ctx
->vc
) / de
;
75 ctx
->q1
= ctx
->vs
* ctx
->t1
+ A_FLOAT_C(0.5) * ac
* ctx
->t1
* ctx
->t1
;
77 ctx
->q
= ctx
->vc
* ctx
->t
+ A_FLOAT_C(0.5) * de
* ctx
->t
* ctx
->t
;
84 a_float
a_traptraj_pos(a_traptraj
const *ctx
, a_float dt
)
88 if (dt
< ctx
->t2
) /* linear motion */
90 return ctx
->q1
+ ctx
->vc
* (dt
- ctx
->t1
);
92 if (dt
< ctx
->t
) /* final blend */
95 return ctx
->q2
+ ctx
->vc
* dt
+ A_FLOAT_C(0.5) * ctx
->de
* dt
* dt
;
99 if (dt
> 0) /* initial blend */
101 return ctx
->vs
* dt
+ A_FLOAT_C(0.5) * ctx
->ac
* dt
* dt
;
106 a_float
a_traptraj_vel(a_traptraj
const *ctx
, a_float dt
)
110 if (dt
< ctx
->t2
) /* linear motion */
114 if (dt
< ctx
->t
) /* final blend */
116 return ctx
->vc
+ ctx
->de
* (dt
- ctx
->t2
);
120 if (dt
> 0) /* initial blend */
122 return ctx
->vs
+ ctx
->ac
* dt
;
127 a_float
a_traptraj_acc(a_traptraj
const *ctx
, a_float dt
)
131 if (dt
>= 0) /* initial blend */
136 else if (dt
>= ctx
->t2
)
138 if (dt
< ctx
->t
) /* final blend */
143 return 0; /* linear motion */