-
Notifications
You must be signed in to change notification settings - Fork 0
/
calc-bounce.c
140 lines (122 loc) · 4.28 KB
/
calc-bounce.c
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
#include <math.h>
#include <stdio.h>
int
main(void) {
double start=40.;
// bounce-in line starts outside the view, all the way to the
// right (so, "41st" column).
double adur=.5;
// time to hit the left wall first time (must be less than dur,
// and > 0.5 * dur)
// total time for the animation to take
double bdur = .5;
double cdur = .25;
double dur=adur + bdur + cdur;
double fps=30.;
// assume the animation is this frames/per second
/*
The formula for what column the line should be printed from
as a function of time, is:
col = start - (t*x)^2
(where x is a scaling factor)
We know col is 0 when t = adur, so
0 = start - (adur*x)^2
Solve for x to find the scaling factor, given start and adur
start = (adur*x)^2
sqrt(start) = adur*x
x = sqrt(start)/adur
x^2 = start/(adur^2)
The velocity here, in columns per sec, is -2 * x^2 * t.
(By differentiating for t.)
*/
double xsqr = start/(adur*adur);
double x = sqrt(xsqr);
/*
For the bounce, we have (dur-adur, = bdur) time. To find the
initial velocity for the bounce (after the text has hit the left edge),
that is, the velocity at t = 0 (we restart the timer at bounce),
we need the positive starting velocity such that when t = bdur/2,
that velocity is zero.
vel = bvel0 - 2 * x^2 * bdur/2 = 0
bvel0 = 2 * x^2 * bdur/2
This gives us the curve for the bounce (by integration):
col = bvel0 * t - (x * t)^2
Don't need to worry about an added constant, bc we know col = 0
at t = 0 (again, t is now "start of bounce", not "start of animation")
*/
double bvel0 = 2 * xsqr * bdur/2;
double cvel0 = 2 * xsqr * cdur/2;
unsigned int numAFrames = adur * fps + 0.5;
unsigned int numBFrames = bdur * fps + 0.5;
unsigned int numCFrames = cdur * fps + 1.5;
unsigned int numFrames = numAFrames + numBFrames + numCFrames;
// + 1 is to guarantee we have at least one final frame at
// column 0 (.byte value 1)
printf("\
;;;; Generated by calc-bounce\n\
\n\
; Generating %u frames at %u fps, to last %f seconds.\n",
numFrames, (unsigned int)fps, dur);
printf("\
; Time to reach left edge the first time: %f seconds (%u frames).\n",
adur, numAFrames);
printf("\
; Time to reach left edge the second time: %f seconds (%u frames).\n",
bdur, numBFrames);
printf("\
; Time to reach left edge the third time: %f seconds (%u frames).\n",
cdur, numCFrames);
printf("\n\
; First byte is frame count, for convenience.\n\
.byte %u\n", numFrames);
const unsigned int framesPerLine = 8;
unsigned int framesLeft = 0;
printf("\n\
; Slide-left frames:\n");
for (unsigned int i = 0; i != numAFrames; ++i) {
if (!framesLeft) {
framesLeft = 8;
printf("\n.byte ");
} else {
printf(", ");
}
double t = i / fps;
unsigned int col = start - (t * t * xsqr) + 0.5; // 0.5 is for round
if (col < 0) col = 0;
printf("%u", col + 1); // add one so we can zero-terminate the list!
--framesLeft;
}
framesLeft = 0;
printf("\n\n\
; Bounce 1 frames:\n");
for (unsigned int i = 0; i != numBFrames; ++i) {
if (!framesLeft) {
framesLeft = 8;
printf("\n.byte ");
} else {
printf(", ");
}
double t = i / fps;
unsigned int col = bvel0 * t - (t * t * xsqr) + 0.5; // 0.5 for round
if (col < 0) col = 0;
printf("%u", col + 1); // add one so we can zero-terminate the list!
--framesLeft;
}
framesLeft = 0;
printf("\n\n\
; Bounce 2 frames:\n");
for (unsigned int i = 0; i != numCFrames; ++i) {
if (!framesLeft) {
framesLeft = 8;
printf("\n.byte ");
} else {
printf(", ");
}
double t = i / fps;
unsigned int col = cvel0 * t - (t * t * xsqr) + 0.5; // 0.5 for round
if (col < 0) col = 0;
printf("%u", col + 1); // add one so we can zero-terminate the list!
--framesLeft;
}
printf("\n\n.byte 0\n");
}