0

in a for-loop with % to get a saw function, for example using a period of 5 printing 2 cycles would look like this:

for(auto i = 0; i < 5 * 2; ++i) cout << i % 5 << endl;

Results in:

0
1
2
3
4
0
1
2
3
4

I want a function returns a triangle wave, so for some function foo:

for(auto i = 0; i < 5 * 2; ++i) cout << foo(i, 5) << endl;

Would result in:

0
1
2
1
0
0
1
2
1
0

Is there such a function, or do I need to come up with my own?

user1118321
  • 25,567
  • 4
  • 55
  • 86
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

3 Answers3

2

Looks like a very similar question was answered here: Is there a one-line function that generates a triangle wave?

Taken from Noldorin answer:

Triangular Wave

y = abs((x++ % 6) - 3);

This gives a triangular wave of period 6, oscillating between 3 and 0.

Now put that in a function:

int foo(int inputPosition, int period, int amplitude)
{
    return abs((inputPosition % period) - amplitude);
}
Community
  • 1
  • 1
Hans Goldman
  • 564
  • 3
  • 12
  • Your function's a little wak there bro. It not only fails to take the input I specified in the question, it also fails to compile cause `x` isn't defined. In any event [Cyber](http://stackoverflow.com/users/2296458/cyber) did do a good job finding that duplicate. – Jonathan Mee Feb 18 '15 at 16:57
  • Right, I just noticed that right before I read your comment. I edited it and should be fixed now. – Hans Goldman Feb 18 '15 at 17:01
  • Getting closer, It still doesn't match the signature specified in the question but it compiles now. (I know we can all imply what you should be doing in `foo`, but we also could have all followed [Cyber](http://stackoverflow.com/users/2296458/cyber)'s link and implied an `foo` from there. If you're going to use someone else's solution to answer this question, it seems like you should at least tailor their answer to the actual question.) – Jonathan Mee Feb 18 '15 at 17:07
  • Sorry, I was already writing the answer when Cyber posted the link. I wasn't just taking it from him. You probably should have done a 2 second Google search before even asking the question. Because that's how long it took me to find that link on my own. Just my 2 cents... – Hans Goldman Feb 18 '15 at 17:12
  • I believe you are correct that I should have taken more time to research, my mistake. Anyway back to working on this answer; it's close to right, have a look at [Eric Bainville's answer](http://stackoverflow.com/a/1073628/2642059) that's the one you want to copy. – Jonathan Mee Feb 18 '15 at 18:32
0

You'd have to make your own:

// Assumes 0 <= i < n
int foo(int i, int n) {
    int ix = i % n;
    if ( ix < n/2 )
        return ix;
    else
        return n-1-ix;
}
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
0

I thought we should at least post the correct answer here before this question is closed cause it is a duplicate.

Eric Bainvile's answer is the correct one.

int foo(const int position, const int period){return period - abs(position % (2 * period) - period);}

However this gives a triangle wave with a range from [0, period] and a frequency of 2 * period and I want a range from [0, period / 2] and a cycle of period. This can be accomplished by just passing half of the period to foo or by adjusting the function:

int foo(const int position, const int period){return period / 2 - abs(position % period - period / 2);}

With such a simple function inlining seems preferable though so our final result will be:

for(auto position = 0; position < 5 * 2; ++position) cout << 5 / 2 - abs(position % 5 - 5 / 2) << endl;

Yielding the requested:

0
1
2
1
0
0
1
2
1
0

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288