Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I make Sine and Cosine waves move smoothly into different waves?

Asked by 6 years ago
Edited 6 years ago

So when using sine and cosine, and switching between how powerful they are, there can be some jagged movement. The reason I am asking is because I am making a game where player input can change the power of the sine and cosine. I made a sample script to show what I mean and people can test (if you want to know what I mean):

local Part = script.Parent
local RS = game:GetService("RunService")


local sine
do
    local frequency
    local phase = 0
    sine = function(amplitude, newFrequency)
        local t = tick()
        if not frequency then
            frequency = newFrequency
        elseif math.abs(newFrequency - frequency) < 0.01 then
            local oldArgument = t*frequency + phase
            frequency = newFrequency
            phase = oldArgument - t*frequency
        end
        print("Sine : " .. (amplitude * math.sin(t*frequency + phase)))
        return amplitude * math.sin(t*frequency + phase)
    end
end


local frames = 0
math.randomseed(tick())
local targetframes = math.random(300, 900)
local cf = true


RS.Stepped:Connect(function()
    frames = frames + 1
    if frames == targetframes then
        frames = 0
        targetframes = math.random(300, 900)
        cf = not(cf)
    end
    if cf then
        Part.CFrame = CFrame.new(-2, 2.5, 10) * CFrame.new(0, (sine(0.3, 1.2)), 0)
    else
        Part.CFrame = CFrame.new(-2, 2.5, 10) * CFrame.new(0, (sine(0.5, 16)), 0)
    end
end)

However when the sine and cosine powers change, there can be some jagged movement, If anyone knows how to make the changes more smooth, it would be greatly appreciated! :)

0
more smooth = more steps, less change Goulstem 8144 — 6y

1 answer

Log in to vote
1
Answered by 6 years ago

Problem here, is that the argument of sine/cosine function changes dramatically once you change the frequency. What you actually want here, is to keep the current argument the same, yet it would change faster on the next iterations.

Fortunately, you can fix this by figuring out by how much the argument has changed for and correct it by adding that difference as sine/cosine function's phase.

That would look something like this:

-- At beginning phase would be 0
local oldArgument = frequency*t + phase
frequency = newFrequency
phase = oldArgument - frequency*t -- Phase is simply the difference between old and new sine function's argument

In order to use this in the way you're currently using it, you'd have to define few local variables, that would remember the phase and frequency of the last function call:

local sine
do -- Using do block, in order to hide "phase" and "frequency" variables from global scope
  local frequency
  local phase = 0

  function sine(amplitude, newFrequency)
    local t = tick()

    if not frequency then
      frequency = newFrequency
    elseif math.abs(newFrequency - frequency) < 0.01 then
      -- Frequency has changed, calculate phase
      local oldArgument = t*frequency + phase
      frequency = newFrequency
      phase = oldArgument - t*frequency
    end

    print("Sine : " .. (amplitude * math.sin(t*frequency + phase)))
    return amplitude * math.sin(t*frequency + phase)
  end
end

Don't have any options to test this, but it should do the job.

Ad

Answer this question