0

(Please bare with me as I try to explain my problem to the best of my abilities)

I have a computer program that draws a sine. Each y value of the sine is stored against the x value in an array like so:

float sine[x] = y;

To find the value of my points, I iterate through each value of x from 0 to 799 using a for loop like so:

etime = 1000000;

int x;
for (x = 0; x < 800; ++x)
{
    sine[x] = sin((x + etime) / 300);
}

Is there anyway I could find the value of sine[x + 1] by using the value of sine[x]?

I want to avoid computing sin((x + etime) / 300) for everypoint on the graph as it costs a lot of memory.

EDIT 1

OK so I trie implementing the solution provided but I realized that I simplified my equation too much for the results to work. This is actually how the equation is calculated:

for(k = 0; k < 799; ++k)
{
    sinewave[k] = 145 * sin((0.984736 * k + etime) / 300) + 0.847563;
}

How do I calculate sinewave[k + 1] if I know sinewave[k]?

ReX357
  • 69
  • Are you sure etime is that big? – user44197 Dec 31 '13 at 07:34
  • @user44197 Yes. It gets even bigger. This is just a dummy value for the purpose of this post. etime is a elapsed time since start of the program and it grows constantly. As mentionned in a comment on the first answer, this is part of a bigger equation of the type A + sin(B * x + C) + D where C is a multiple of etime and constantly increases making it look like the wave is constantly shifting left. This sine is recalculated 60 times a second roughly. – ReX357 Dec 31 '13 at 07:37
  • If etime increases by known amount and this is a multiple of 300, then you can reuse the array. You just have to rotate the array (or shift pointers). If you use C++ then using smart pointer will automatically turn your array into a circular list. When accessing arrays, pointers are more efficient and you can change the origin of the array by pointer arithmetic. – user44197 Dec 31 '13 at 07:51
  • @user44197 Let me elaborate a little more on what I'm accomplishing here. Basically, I calculate a sine using form A + sin(B * x + C) + D. Now A and B (The period) are calculated with an equation of the same form. The point is to make the sine look random over time. So the amplitude(A) oscillates over time and the period (B) does as well. The final equation for the sine is something that looks like sin + sin(sin * x + C) + sin. The point of this whole thing is to create and effect like the background of the PS3 operating system where the sines look randomized over time. – ReX357 Dec 31 '13 at 07:58
  • Ok. It is very late here. Not sure how you can send me a message, but if you do, I can try and help you tomorrow. It is 3 AM here and I need sleep! – user44197 Dec 31 '13 at 08:19
  • @user44197 Can you have a look at the edit on my post? – ReX357 Dec 31 '13 at 18:09
  • @ReX357 You want to have a sine wave whose amplitude and period are changing over time? The amplitude isn't a big deal, but while not hard to implement, dealing with a changing period is a bit weird (see http://math.stackexchange.com/questions/568726/terminology-re-continuity-of-discrete-a-sint) – Mark S. Jan 08 '14 at 05:07
  • @MarkS I wish you would of replied a week ago when I was still banging my head with this problem. I ended up giving up and going in a different direction. If I'd known about the phase I could of probably made the whole thing work. – ReX357 Jan 08 '14 at 05:19

3 Answers3

3

Yes there is. Use this recurrence relationship

$$ \text{sine}[x+2] = \alpha\, \text{sine}[x+1] + \beta \,\text{sine}[x]$$ where $\alpha$ and $\beta$ depend on the resolution.

If you need more help, leave me a comment and I can show you how to find $\alpha$ and $\beta$

Added based on OP's request.

Let sine[x] = sin(t), sine[x+1]= sin(t+\delta) and sine[x+2]= sin(t+ 2\delta)

$$ \sin(t+2\delta)+\sin(t) = \\\sin(t+\delta) \cos(\delta) + \cos(t+\delta)\sin(\delta) + \sin(t+\delta)\cos(\delta) - \cos(t+\delta)\sin(\delta)$$ So $$\text{sine}[x+2] = 2 \cos{\delta} ~~\text{sine}[x+1] - \text{sine}[x] $$

In your case $\delta = \text{etime}/300$. So $$ \alpha = 2 \cos ( \text{etime}/300),~~\beta = -1$$

user44197
  • 9,730
  • Need more help!!! How do I find a and b? – ReX357 Dec 31 '13 at 07:24
  • Use $\sin(x\pm dx)=\sin x\cos(dx)\pm\cos(x)\sin(dx)$ and add both variants. -- However, the numerical reliabilty will suffer after some time. And etime is rather large, is that really necessary? – Lutz Lehmann Dec 31 '13 at 07:29
  • etime is elapsed time. It's in centiseconds. This graph gets updated roughly 60 times a second and this equation is really part of a bigger equation of the type A + sin(B * x + C) + D where C is the X offset of the sine wave and is driven by etime. It makes it look like the wave is constantly shifting left. – ReX357 Dec 31 '13 at 07:32
1

So I ended using this trig identity to replace the sin call:

sin(a+b) = sinAcosB + sinBcosA.

I was able to precompute all the values and store them in lookup tables which lowered my sin function call count from 12800 calls down to 8 calls per frame.

ReX357
  • 69
1

Have you tried solving the IVP: y'' = -y ; y'(0)= 1 ; y(0)=0 , numerically? The IVP has the unique solution of y(x) = sin(x) and there are a ton of tools for solving IVPs numerically.

You can express the second order ODE as a system of ODEs, let u = y' , then you can have the system

y' = u

y'' = u' = -y

Then use something like the Euler method for systems of ODEs which will let you solve for y(x)=sin(x) at each x: http://people.wallawalla.edu/~ken.wiggins/341w2008/LectureNotes/systemsofdifferentialequationsoutline.pdf

(there's better methods but Euler's method is relatively simple and I don't have any references on me, also that reference specifically solves the system for sin(x) )