efficient triangle to sine morphing? I'm coding a synthesis external for MaxMSP in C. 
It's based on Peter Blasser's bounds and bounce concept ( http://petermopar.blogspot.co.uk/2014_04_01_archive.html )- basically triangle waves with constant cursor rate (rather than frequency) and modulated bounds - eg instead of moving between -1 and 1, the wave moves between lo and hi, with lo and hi modulated.

This morning I've been thinking of adding waveshape morphing between triangle and sine (or at least sinusoidal since the moving bounds will deform the sine). 

I can think of a fairly simple way to do this:

// Assuming classic triangle moving between bounds -1 to 1 
// and defining position of triangle cursor @ n = pos
// shape_amt between circa 0.1 (Tri) and 1.0 (sine)
out = sin(pos * shape_amt * 0.5* pi ) / sin(shape_amt *0.5 * pi())


ie - basic waveshaping technique - scale the portion of the lookup table that's being scanned (in this case some segment of half a sine wave) to vary the shape.

For my specific case all I'll need to do from there is build in scaling from relative position between to bounds to relative position between -1 and 1.

My question really is- is this a horribly inefficient way of achieving what I'm after? I'm new to DSP coding and to coding in C so I'm sure the way that's most obvious to me isn't the best. 

The obvious performance improvement that occurs to me is to create a wavetable of the sin function and look up rather than calculate those values. Obviously that way I lose resolution on the "straighter" portions of the wave, but either a high res lookup or decent interpolation feels like it ought to deal with that fairly well. Mainly I'm considering this for LFO applications so quality needn't be utterly stellar (though it'll be nice nice if it's useable into the audio range without too much fuzzy aliasing).

But beyond that, is there just a completely different approach that would be more efficient? 
And if this is the best approach, are there any things I should think of when pursuing it?

Edit - Thanks for great answers below. I've ended up doing something fairly simple (and possibly crude) for the moment, which suits my purposes pretty well. I'll definitely be investigating both suggestions as improvements to this.

#define sign(a) ( ( (a) &lt; 0 )  ?  -1   : ( (a) &gt; 0 ) )
#define LKTBL_LNGTH 2048

void setup_lktables (t_object* x)
{   // create lookup for 1/4 sine
    int i;
    for(i=0, i&lt; LKTBL_LNGTH, i++){
        x-&gt;sin[i] = sin(pi * i * 0.5 / LKTBL_LNGTH) ;
    }
}

double lookup_shape (t_double pos, t_double shape, t_double lo, t_double hi) 
// acting on triangle wave (phase + (2*gradient*f/sr) per sample, wraps &amp; changes dir  at &lt;lo and &gt;hi)
// shape comes in as restricted to (-1...-0.05, 0.05 ...1), defines the portion of lookup to use

{
    t_double midpoint, halfwidth, ph, fracph, shaped;
    t_int maxph, intph, sign;
    // get relative position between bounds for waveshaping lookup
    midpoint = lo + 0.5f * (hi - lo);
    halfwidth = midpoint - lo;
    // prepare phase values for lookups
    maxph = shape * LKTBL_LNGTH - 1;
    ph = (pos - midpoint) * maxph /  halfwidth;
    sign = sign(ph);
    ph = ph * sign;
    intph = (int)ph;
    fracph = ph - intph;
    // lookup, scale &amp; lerp
    shaped = sign * (x-&gt;sin[intph] * (1.f - fracph) + x-&gt;sin[intph+1] * fracph) / x-&gt;sin[maxph];

    //now return  waveshaping output scaled to actual bounds
    return midpoint + shaped * halfwidth
}
This answer is about using sines instead of triangles in the bounds and bounce concept. There is no way to do it so that these defining conditions of the original concept are all satisfied:


While the boundaries stay constant the output is a pure sine wave (triangle for the original algorithm) that goes from the upper boundary to the lower boundary.
Moving the boundaries suddenly does not create a discontinuity in the output.
Moving the boundaries suddenly does not create a discontinuity in the derivative (slope) of the output.


Say the sine wave has reached the upper boundary and the boundaries are updated. Sine waves of other amplitudes cannot have zero derivative at that amplitude value, so the scheme fails.

But you can make it work if you constrain the boundary changes to times of zero crossings of the sine wave:



You just have to decide on the slope at zero crossing and your sine turns out as:  $$\text{boundary}\times\sin\left(\frac{\text{slope}\times\text{time}}{\text{boundary}}\right).$$