5
$\begingroup$

This question is specifically about the terminology used to explain a particular problem and its solution, not the math itself. I am a programmer, I am not really a math person, but I have at least an intuitive understanding of the concepts I frequently encounter in computer graphics.

Recently a friend was doing some computer animation work that involved a sine wave with an amplitude and period that were functions of time. Let's call value $V$, amplitude $a$, period $p$, time $t$. He ran into a classic problem where he was doing:

$$ V(t)=a(t)\sin\left(\frac{2\pi t}{p(t)}\right) $$

With $t$ set to the elapsed time since the start of the program, i.e. $t=t_\text{now}-t_\text{start}$. The problem, of course, is that as $p(t)$ changed, all sorts of artifacts were visible and the sine wave did not smoothly transition in apparent speed. He asked how to solve this problem. I explained to him that he instead needed to work with the current phase instead of absolute time, incrementing each frame based on the period, like so (initializing $t$ to 0):

$$ t = t + \frac{\Delta t}{p(t)} $$ $$ V(t)=a(t)\sin(2\pi t) $$

Then I awkwardly launched into some explanation (that ultimately required a pen and paper) about how you want to "smoothly move around the circle, incrementing so that changes in speed don't jump to far away positions" rather than "jumping between graphs of sine waves of different frequencies" or something. In the end he got it, and fortunately he intuitively understood what I was trying to say, but I did a really poor job of explaining it.

So my first question is, and apologies if this is asking too much, but how would you explain this to somebody, succinctly, using proper math terms? I realize there are many answers, but currently I know 0 answers. How can I explain to somebody why incrementing the phase based on $\Delta{t}$ and $p(t)$ leads to continuity, while calculating the value based on the total elapsed time doesn't?

My second question is this: My friend then asked me, "do I need to do the same with amplitude?" The answer is no (assume that the "continuity" of $a(t)$ is "good enough"). I couldn't explain why, though. I mean, intuitively, I knew why, and I said, "No. I don't know the math term for it but the $a(t)$ is outside the $\sin()$ so it works out." What are the words I was looking for there? How can I explain to somebody that $a(t)$ doesn't suffer the same problem as the $t/p(t)$ did? I know it has something to do with the way $\sin(x)$ varies with $x$, but I don't know the proper way to describe it.

My third question is that at some point during this process I was explaining why the two equations above were identical for a constant $p(t)$. My explanation involved something like, "Well, I mean, the elapsed time is the same as all of the delta times added together, so you can see if you pull these terms out of the $\sin()$ and increment instead, the value is the same." Even typing that, it makes very little, if any, sense. On paper I wrote:

The original:

$$t=t_\text{now}-t_\text{start}$$ $$\sin\left(\frac{2\pi t}{p(t)}\right)$$

Is the same as:

$$t=t+\Delta t$$ $$\sin\left(\frac{2\pi t}{p(t)}\right)$$

Is the same as:

$$t=t+\frac{\Delta t}{p(t)}$$ $$\sin\left(2\pi t\right)$$

When $p(t)$ is a constant function.

... but I couldn't explain why. How can I explain to somebody that incrementing by deltas every frame is the same as the difference between the current frame and the first frame? Is there some terminology that fully encapsulates this so that an example is not necessary?

Heck, I don't even know what the fundamental problem is called, I always just refer to it as an "artifact" in a generic sense.

How would you explain this problem and its solution to somebody?

Note: I realize I am liberally interchanging "time" (i.e. seconds) and "phase" above -- this is really just another symptom of my inability to express these thoughts clearly.

Update:

I have created two JavaScript demos that try and illustrate the problem:

The first example is a more typical case in my experience. The second example shows the problem very sharply and may be more illustrative.

Basically, my question is: How could I explain why the incorrect approach is incorrect, and why the correct approach is correct, without using pictures or animated examples, but instead with proper and clear mathematical language?

$\endgroup$
  • 1
    $\begingroup$ To confirm: The goal is to draw an animated sine wave whose amplitude and period vary with time? If so, the function being plotted depends on both time $t$ and phase $\theta$, and so needs to be written as a function of two variables, something like $V(\theta, t) = a(\theta, t) \sin\bigl(2\pi\theta/p(t)\bigr)$. $\endgroup$ – Andrew D. Hwang Nov 20 '13 at 1:19
  • $\begingroup$ A link to some example code (or pseudocode) where the artifacts are visible and some where they're not would make it a lot easier to explain what you want to explain (and point out errors in your reasoning, if any exist). $\endgroup$ – Mark S. Nov 20 '13 at 13:06
  • $\begingroup$ @user86418 Yes that is the goal. I do no think the function is correct though. Phase depends on period. I think, more specifically, phase is the integral of 1/period. Essentially the correct approach is something like computing a discrete integral, maybe. The link I'm about to post may clear it up. $\endgroup$ – Jason C Nov 22 '13 at 8:31
  • 1
    $\begingroup$ @MarkS. I've put together a JavaScript demo at 03781fb.netsolhost.com/problem.html. I tried my best to keep the examples illustrative and minimal. Does that clear it up? Basically, my question is: How could I explain why the incorrect approach is incorrect, and why the correct approach is correct, without using pictures or animated examples, but instead with proper and clear mathematical language? $\endgroup$ – Jason C Nov 22 '13 at 8:32
  • 1
    $\begingroup$ @MarkS. I have added a second demo at 03781fb.netsolhost.com/problemstep.html where I am using a step function for period. The difference between the incorrect and correct methods is very sharp here. $\endgroup$ – Jason C Nov 22 '13 at 8:46
4
+100
$\begingroup$

The period of the function $f(t) = \sin\bigl(t \cdot (2\pi/k)\bigr)$ "at $t$" is $k$, regardless of $t$. The question is how to extend the definition if the period is not constant.

The "period" of the function $f(t) = \sin\bigl(P(t)\bigr)$ at $t$ is reasonably defined to be $2\pi$ times the reciprocal rate of change of phase with respect to $t$, i.e., $2\pi/P'(t)$. That is, the steepness (not the magnitude) of $P$ determines the "variable period".

So, if the "variable period" $p(t)$ is to be specified, then $p(t) = 2\pi/P'(t)$. The function $P(t)$ is then found by integrating $2\pi/p(t)$. This is what your numerical scheme approximates.

The "non-working" strategy treats the constant period $k$ as an algebraic parameter (and replaces it by a non-constant function $p(t)$), rather than as a reciprocal rate of change, $2\pi$ divided by the derivative of $P(t) = 2\pi t/k$.

Amplitude, by contrast, is simply the magnitude of $a(t)$, so the "incorrect" scheme for period "works" for amplitude.

$\endgroup$
  • 1
    $\begingroup$ I accepted this answer and awarded the bounty because it's a very succinct, clear answer that precisely describes the issue, and gives a clear description that doesn't require pictures and demos and hand-waving. Mark's answer was also awesome and immensely helpful, but the simplicity of this one is what I was looking for. Thanks guys! $\endgroup$ – Jason C Nov 25 '13 at 22:00
  • $\begingroup$ Period is essentially the inverse of angular speed. The fundamental problem, then, I think, is forgetting that position (angle in this case) is the integral of speed (plus a constant starting point), not time*speed (which just happens to be the integral for constant speed). The shortcut for constant speed, position=time*speed, works because it is the integral of speed when speed is constant. But non-constant period/speed mean that the shortcut is no longer appropriate, and the solution is to approximate the integral instead of relying on the insufficient linear function. $\endgroup$ – Jason C Nov 25 '13 at 22:15
  • 1
    $\begingroup$ @JasonC That's very fair; thank you for taking the time to explain (you didn't have to do that). Yes, your summary sounds correct for the non-$a(t)$ questions. $\endgroup$ – Mark S. Nov 26 '13 at 0:03
  • $\begingroup$ @Andrew D. Hwang This is actually an application of tangent curves. Since $\sin{(P'(a)(x-a)+P(a))}$ is always tangent (has the same tangent line) to $\sin(P(x))$ at $(a,\sin{(P(a))}$ and thus the period is $\frac{2\pi}{P'(a)}$. $\endgroup$ – Arbuja Nov 11 '15 at 16:33
4
$\begingroup$

Example Results

To make this more self-contained, I'll paraphrase the two pairs of example results linked in the OP.

"The goal is a sine wave where period is a function of x. Example uses period=80 at x=0, decreasing linearly to period=20 at x=600, then holding at 20 (x range is 0 to 800)."

Good: good1

Bad: bad1

"The goal is a sine wave where period is a function of x. Example uses a step function where period=80 for x<390, and period=120 for x>=390."

Good: good2

Bad: bad2


Explanations

0. Explaining the goal

The examples in the OP made it clear what we're looking for on an intuitive level, but what does "a sine wave where period is a function of x" really mean? For it to be called a wave at all, it better be continuous. But to have a "period" at a particular time, we need to figure out a way to detect the period of a sine wave based on local information, and we can use that as our definition. I claim that if $|f'(t)|$ at the point is the same as the derivative of the sine wave of appropriate period $p$ when that sine wave is at height $f(t)$, then we should say "the period of $f$ at $t$ is $p$" (note that when $f(t)=\pm1$ then $|f'(t)|=0$ and "the period at $t$ is $p$" is true for all $p$).

Justification for claim (you can skip this if it's geometrically intuitive):

If we have a sine wave of constant period $p>0$ (and amplitude $1$), then we may as well pick $s(t)=\sin(2\pi t/p+\phi)$, and I claim we can detect the period via the use of the derivative: $s'(t)=(2\pi/p)\cos(2\pi t/p+\phi)$. Note that $$|s'(t)|=\frac{2\pi}p\sqrt{\cos^2(2\pi t/p+\phi)}=\frac{2\pi}p\sqrt{1-\sin^2(2\pi t/p+\phi)}=\frac{2\pi}p\sqrt{1-\left(f(t)\right)^2}\text{,}$$ so that $p=2\pi\sqrt{1-\left(s(t)\right)^2}/|s'(t)|$. If you have two sine waves with the same height and derivative-magnitude somewhere, then they have the same period. Conversely, since you can solve that last equation for $|s'(t)|$, if they have the same height and the same period, then they have the same derivative-magnitude (this makes sense because one could be going up and the other could be going down).

1a. Why does the good method work?

The OP said "Essentially the correct approach is something like computing a discrete integral, maybe." Indeed, the result of adding $(\Delta t)/p\left(t\right)$ to $t$ at each stage (for small $\Delta t$) is an approximation to $\int_{0}^{t}1/p\left(\tau\right)\,\mathrm{d}\tau$. The good method is approximating a function like $$f(t)=\sin\left(2\pi\int_{0}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)\text{.}$$ For the period to be correct, we expect that to have derivative (at least up to a sign change) $$\frac{2\pi}{p(t)}\cos\left(2\pi\int_{0}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)$$ at every point of continuity of $p$, and by the chain rule and the fundamental theorem of calculus, we can see that it does. Furthermore, the sign of $f'$ doesn't suddenly flip because even though $p(t)$ suddenly changes at points of discontinuity, it's still positive everywhere, and the cosine part is of the derivative is continuous because integrals like this of reasonable functions are always continuous (see Lemma 6.1 in these lecture notes).

1b. Why does the bad method fail? and 3. But why not if $p$ is constant?

In part 0, we said that having the right period at a given height means having the right $|f'(t)|$. We just have to show that in general, the bad method doesn't give us that. If we use $f(t)=\sin(2\pi t/p(t))$, then we expect a derivative of $(2\pi/p(t))\cos(2\pi t/p(t))$ but (assuming $p$ is differentiable) we get a derivative of $$2\pi\left(\frac{\mathrm{d}}{\mathrm{d}t}\frac{t}{p(t)}\right)\cos\left(2\pi\frac{t}{p(t)}\right)=2\pi\left(\frac{1}{p(t)}-t\frac{p'\left(t\right)}{\left(p\left(t\right)\right)^{2}}\right)\cos\left(2\pi\frac{t}{p(t)}\right)\text{.}$$ The error in this method is caused by the term with $-tp'(t)/\left(p(t)\right)^2$, which is zero when $t=0$ (the starting point), $\cos=0$ (the function is $\pm1$ so the derivative is just $0$), or $p'(t)=0$ ($p$ is constant near $t$).

But what about if $p$ is constant on two sides of a jump discontinuity? Then $sin(2πt/p(t))$ will likely be discontinuous there. That's a different problem with the bad method compared to what I explained above, which covers the first example but didn't really explain the step function example.

2. What about $a(t)$?

First note that if $a(t)$ is constant and positive, you can just stick $a$ in front of all the formulas above and nothing really changes. Now, the OP's examples both had $a=1$, but I'm going to assume the goal is things that still look like sine waves. The solutions discussed above are sine waves with minimum $-1$ and maximum $1$, so if we want to stretch/squish things vertically at the input $t$ by a factor of $a(t)$, we replace $y$ by $y/(a(t))$ (just like horizontal stretch by a constant factor is replacing $t$ with $t/p$). But $y/(a(t))=\sin(\text{whatever})$ is equivalent to $y=a(t)*\sin(\text{whatever})$. It's not like horizontally stretching which could mess up nearby points; we do this at every $t$ independently, so there's nothing else to worry about.


Bonus: How could we find all good methods?

Let's forget about this discrete situation for a second, and ask ourselves the following: Suppose that $p(t)$ is some piecewise continuous, strictly positive, function. Which continuous function(s) $f(t)$ with $|f(t)|\le1$ have period $p(t)$ at every point of continuity of $p$ and signs of the left and right derivative match up wherever $p(t)$ is discontinuous? We can break this up into two parts: solving the problem for continuous $p$, and stitching the solutions together for other $p$.

Continuous period functions

Our earlier work tells us that the having period $p(t)$ means $|f'(t)|=2\pi\sqrt{1-\left(f(t)\right)^2}/p(t)$, where this makes perfect sense since $|f(t)|\le1$ and $p(t)>0$. This may look a little scary, but it's essentially a separable differential equation: $$\left|y'\right|=2\pi\sqrt{1-y^{2}}/p\left(t\right)\Rightarrow\frac{\mathrm{d}y}{\mathrm{d}t}=\pm2\pi\sqrt{1-y^{2}}/p\left(t\right)$$ If $\left|y\right|=1$, then $\mathrm{d}y/\mathrm{d}t=0$. Otherwise, we can divide to get: $$\frac{1}{\sqrt{1-y^{2}}}\mathrm{d}y=\pm\frac{2\pi}{p\left(t\right)}\mathrm{d}t\Rightarrow\arcsin y=\pm2\pi\int_{t_{0}}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau+C$$$$\Rightarrow y=\sin\left(\pm2\pi\int_{t_{0}}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau+C\right)$$ (Note that for these $y$, $\mathrm{d}y/\mathrm{d}t=0$ whenever $\left|y\right|=1$, so we didn't really lose that special case.)

To generate the pictures like in the examples, we should force $f(0)=0$ and $f'(0)>0$. The first condition makes $C=2\pi k$ or $C=\pi+2\pi k$, but $\sin(x+\pi+2\pi k)=-\sin x=\sin(-x)$, so the $\pm$ sign allows us to safely take $C=0$. Since $f'(0)=\pm(2\pi/p(0))\cos(0)$, we should pick the $+$ sign, and for continuous $p$ we have the solution $$f(t)=\sin\left(2\pi\int_{0}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)\text{.}$$

Arbitrary period functions

Now, if $p$ is discontinuous, we might have to break this into separate cases. Suppose $p$ is first discontinuous at $t_1>0$, with left limit $p_\ell(t_1)$ and right limit $p_r(t_1)$. Then the solution to the left of $t_1$ is given by the formula above, and has (left) derivative at $t_1$ given by $$\frac{2\pi}{p_\ell(t_1)}\cos\left(2\pi\int_{0}^{t_1}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)\text{.}$$ Since $f$ is supposed to be continuous at $t_1$, the solution to the right of $t_1$ is given by $$\sin\left(\pm2\pi\int_{t_{1}}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau+2\pi\int_{0}^{t_1}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)$$ for a certain choice of sign for $\pm$. The (right) derivative at $t_1$ is then given by $$\pm\frac{2\pi}{p_r(t_1)}\cos\left(\pm2\pi\int_{t_{1}}^{t_1}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau+2\pi\int_{0}^{t_1}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)=\pm\frac{2\pi}{p_r(t_1)}\cos\left(2\pi\int_{0}^{t_1}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\right)\text{.}$$ Since $p_\ell(t_1),p_r(t_1)>0$, the sign matches up correctly when the $+$ sign is chosen. We can repeat this argument at each discontinuity, so that the original formula $f(t)=\sin\left(2\pi\int_{0}^{t}(1/p\left(\tau\right))\,\mathrm{d}\tau\right)$ still works as written even for discontinuous $p$!

Discretization

A standard way to discretize the above exact solution is by replacing the integral in the above along the lines of $$\int_{0}^{t}\frac{1}{p\left(\tau\right)}\mathrm{d}\tau\rightsquigarrow\sum_{k=1}^{t/\Delta t}\frac{\Delta t}{p\left(k\Delta t\right)}\text{.}$$ But that's just the "right-hand sum". You could use the left-hand sum or a trapezoidal rule or Simpson's rule, etc. Now that we know that the exact solution involves an integral, we can use any simple or advanced method for approximating that integral.

$\endgroup$
  • $\begingroup$ Thank you so much for taking the time to put this together. It's extremely help and informative, and if I were to envision a how-to or writeup about the problem I described, this is the perfect explanation. I accepter user86418's answer because I think it is a succinct and appropriate explanation, suitable for explaining the problem precisely to somebody verbally, which is more the situation I find myself in. I wish I could accept both. I might have some questions about this answer, and I will think about it this evening. Thanks again! $\endgroup$ – Jason C Nov 25 '13 at 22:04
  • $\begingroup$ Oh, and, yes, I left amplitude out of the examples, but your assumption that it still "looks like" a sine wave is correct. The rate of change of $a(t)$ is very low compared to the frequency of the sine wave. Handling sudden changes in $a(t)$ is situation-specific (e.g. in audio signal generation it's common to set a limit on the maximum rate of change to avoid audible artifacts, whereas in an interactive setting where the output is visual, the discontinuity may be acceptable). $\endgroup$ – Jason C Nov 25 '13 at 22:31
  • 1
    $\begingroup$ @JasonC, I'm glad this was helpful, even if it wasn't the succinct explanation you were looking for. If you have any questions about my answer I'd be happy to respond. $\endgroup$ – Mark S. Nov 26 '13 at 0:08
2
$\begingroup$

The term I think your looking for is 'change of variables'. However (as you admit) your phrasing and notation makes it hard to see. I'll write out here what I think you want to do and can edit it if its wrong.

You have the function $$ V(t)=a(t)\sin\left(\frac{2\pi t}{p(t)}\right) $$ and you want to plot it by considering a set of values $t_n$ where you get from one to the next by $$ t_{n+1}=t_n+\Delta t_n $$ and $\Delta t_n$ is your step size which might vary. The function changes rapidly in some areas and slowly in others, specifically is second derivative, you plot straight lines and thus it is the rate at which the function deviates from the straight lines that causes you problems when considering constant step size.

A solution is to change variables into a new 'rescaled time' which we shall denote as $s$, and define as $$ s=\frac{t}{p(t)} $$ In this variable we shall make steps of constant size, and time steps that should be taken in the variable $t$ can be reverse engineered from our step in $s$. Let us denote our constant step size in $s$ as $\Delta s$. Thus $$ s_{n+1}=s_n+\Delta s $$ using the definition of $s$ we get \begin{align} \frac{t_{n+1}}{p(t_{n+1})}&=\frac{t_n}{p(t_n)}+\Delta s \\ \therefore \: \Delta s&=\frac{t_{n+1}}{p(t_{n+1})}-\frac{t_n}{p(t_n)} \\ &\approx\frac{t_{n+1}}{p(t_{n})}-\frac{t_n}{p(t_n)} \\ &=\frac{\Delta t_n}{p(t_n)} \end{align} And finally we can time-step as $$ t_{n+1}=t_{n}+\Delta t_n\approx t_{n}+p(t_n)\Delta s $$ I assume this is equivalent to whatever you are using, It cant be what I think your saying since that wouldn't fix your problem!

Rereading your question there are several things wrong so I'll try to tackle them, I think I've already answered your first one.

If a(t) as approximately constant then no, you done need to rescale it, but only because you can say $a(t)\approx a$, in which case you shouldn't consider it to be a function but rather a constant. If you consider it to be a function then YOU MUST RESCALE!

Increasing the value by a small increment must be the same as the total time elapsed. A full text-based explanation would be tricky, but if you draw a time-line with all $t_n$ marked on then the difference between two adjacent is a step, and the total between beginning and current times as the sum of all steps. Just draw the picture!

I think you have ended up with a programme which plots a function different than the one you want to. Notice that the difference between 'correct' and 'incorrect' in your examples is more than just plotting accuracy. The 'incorrect' method plots the correct function poorly and the 'correct' method plots the incorrect function poorly. Youve just done it wrong! Try making the adjustments here and see what happens.

$\endgroup$
  • $\begingroup$ Note: this will only work if $p(t)\neq0$ for all time plotted. Nothing will help you there! $\endgroup$ – Eddy Nov 23 '13 at 15:22
  • $\begingroup$ To stress once again, your question is more than just terminology. The reason you couldn't convince your friend was because this is wrong, and I'm happy to try and help you understand. Here/skype whatever. $\endgroup$ – Eddy Nov 23 '13 at 15:57
  • $\begingroup$ Thanks, I appreciate this and it is helpful. I am slightly confused because my solution actually is correct. It behaves correctly and is a widely-used and time-tested strategy. Think of it like this (the other answers here helped me think about it this way): Say you have a basic physics simulation with an object moving at non-constant speed. It's insufficient to simply say position = speed * time, because speed is non-constant. Instead, every step, you increment position by the current speed * timestep. It is the same here: The period is the inverse of angular speed... $\endgroup$ – Jason C Nov 25 '13 at 22:07
  • $\begingroup$ ... so it's not sufficient to say y = sin(angular_speed * time) because angular_speed is non-constant. Instead, you must approximately integrate, and increment angle by current angular_speed * timestep. The problem is an incorrect calculation of position - position is the integral of speed (plus a constant starting offset), it just happens to equal timespeed for constant speed, but when speed isn't constant, timespeed is no longer the integral. We (I? Classrooms?) so often take shortcuts that assume constant speed that it's easy to forget the real definition of position as integral. $\endgroup$ – Jason C Nov 25 '13 at 22:12
  • $\begingroup$ It is worth noting, too, that the "correct" example does plot the correct function (albeit poorly), which is essentially "a sine wave that looks like it is 'slowing down'", for lack of a better explanation. I think it is a poor plot perhaps because of a low sample rate, but it is accurately poor (if that makes sense) because it is representative of the approximation in a discrete system and the actual results produced, even if it isn't a precise discrete sampling of the "correct" continuous function. It is "good enough". $\endgroup$ – Jason C Nov 25 '13 at 22:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.