Jump to content

Wavelength with gradual frequency change?


Recommended Posts

Bit of a strange one, but here goes my first post.

 

I did a quick search and haven't been able to find one, but is there a plug-in or method that will allow me to create a kind of waveform (like a sine wave sort of) where the "frequency" gradually gets longer/shorter?

I could try doing it by hand, but it would irritate me like an itch knowing that it's not perfect, even if I got it to look good.

This is a quick drawing of what I'm kind of after:
o91e9x.jpg

 

A bit rough, just a quick scribble to get the idea across.

 

So any ideas how to achieve this kind of pattern?

Link to post
Share on other sites

Or maybe this one: Sound Wave

 

Edit: maybe not. I was thinking of something else.

Link to post
Share on other sites

Or maybe this one: Sound Wave

 

Edit: maybe not. I was thinking of something else.

Was thinking of Ed Harvey's Seismograph

:lol: WEOAMP :lol:

:P
Link to post
Share on other sites

Here's my plugin: GraphSine.zip

 

It's under Effects>Render>Graph Sine. The Help menu is just a stub which I'll probably improve. It draws in the Primary Color on a Secondary Color background. I haven't updated CodeLab yet, so it uses two place precision on the slider (which is probably enough).

 

Here's the source:

Hidden Content:
// Name: Graph Sine
// Submenu: Render
// Author: MJW
// Title: Graph Sine
// Desc: Graph a variable-frequency sine wave
// Keywords: graph sine
// URL:
// Help: [b]Graph Sine[/b] graphs a sine wave whose frequency can vary from the beginning to the end. The size is adjusted to fill the current selection.

#region UICode
DoubleSliderControl Amount1 = 1; // [0.01,100] Beginning Frequency
DoubleSliderControl Amount2 = 1; // [0.01,100] Ending Frequency
DoubleSliderControl Amount3 = 1; // [0,4] Amplitude
DoubleSliderControl Amount4 = 0; // [-1,1] Phase (in cycles relative to beginning frquency)
DoubleSliderControl Amount5 = 1; //[1,10] Line Thickness.
CheckboxControl Amount6 = false; //[0,1] Overwrite
#endregion

DoubleSliderControl prevAmount1 = -1;
DoubleSliderControl prevAmount2 = -1;
DoubleSliderControl prevAmount3 = -1;
DoubleSliderControl prevAmount4 = -1;

Point[] function = null;
int xSteps;

void Render(Surface dst, Surface src, Rectangle rect)
{  
    Rectangle sel = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 
    
    if (function == null)
    {
        xSteps = sel.Width;
        function = new Point[xSteps];
        prevAmount1 = Amount3 - 1.0;
    }
     
    // If any of the controls which affect the graph change, update the graph.
    if ((prevAmount1 != Amount1) ||
        (prevAmount2 != Amount2) ||
        (prevAmount3 != Amount3) ||
        (prevAmount4 != Amount4))
    {
        prevAmount1 = Amount1;
        prevAmount2 = Amount2;
        prevAmount3 = Amount3;
        prevAmount4 = Amount4;
               
        // t will go from 0 to 1 across the selection.
        double tStep = 1.0 / (double)(xSteps - 1);
        
        double xScreenScale = (double)(sel.Width - 1);
        double xScreenOffset = (double)sel.Left;

        double yLow = -1.0;
        double yHigh = 1.0;        
        double yRange = yHigh - yLow;

        double yScreenScale = -(double)(sel.Height - 1) / yRange;
        double yScreenOffset = (double)sel.Top - yScreenScale * yHigh;

        double aScale = 2.0 * Math.PI;
        double aOffset = -Amount4 * aScale / Amount1;
        
        double fScale = Amount2 - Amount1;
        double fOffset = Amount1;
        
        double t = 0.0;
        for (int i = 0; i < xSteps; i++)
        {
            double f = fScale * t + fOffset;
            double a = aScale * t + aOffset;
            int screenX = (int)(xScreenScale * t + xScreenOffset + 0.5);
            double y = Amount3 * Math.Sin(f * a);
            //y = 0.1 * a * f;
            int screenY = (int)(yScreenScale * y + yScreenOffset + 0.5);         

            function[i] = new Point(screenX, screenY);         
           
            t += tStep;
        }
    }

    // Clear the ROI or copy it.
    if (Amount6)
        dst.CopySurface(src, rect.Location, rect);
    else
        dst.Clear(rect, EnvironmentParameters.SecondaryColor);

    // Create a pen to draw with and a graphics object to draw on.
    // Then draw the graph.
    using (Pen myPen = new Pen(EnvironmentParameters.PrimaryColor))
    using (Graphics g = new RenderArgs(dst).Graphics)
    {
        myPen.Width = (float)Amount5;     
        g.Clip = new Region(rect);
        // Set the smoothness mode.
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        // Now draw the function.
        g.DrawLines(myPen, function);
    }
}


 

EDIT: I will, of course, consider suggestions for improvements, though I hope I don't have to spend too much time on this plugin.

 

EDIT2: Fixed bug that resulted from a mistake I made when renumbering the Amount variables. The problem might not be noticeable, but it could cause the graph not to update when it should, or it could cause the plugin to run slower. I'm considering redesigning the algorithm. I go to considerable effort to avoid recalculating the graph for each ROI. It may not be worth it. It would probably run fast enough without the complexity.

 

EDIT3: I think I'll keep the algorithm as it is. "Considerable effort" is an overstatement. It's really just a matter of keeping track of whether any of the controls that affect the graph have changed since the graph was last computed.

Link to post
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...