 # Using trigonometry to make an oscillating wave?

I tried amplitude * math.sin(CurTime()) to vertically oscillate the velocity of the entity, but the entity hits the ground and stays there for several seconds while accelerating downwards.

How do I vertically adjust it without effecting the amplitude?

Also, how do I adjust the speed of the oscillation?

By vertically adjust do you mean you just want to move it up a certain amount? Just add the amount on outside of the multiplication.

``````
amplitude * math.sin(CurTime()) + verticalOffset

``````

By increasing the time, eg to make it twice as fast, CurTime()*2

``````
amplitude * math.sin(CurTime()*oscillationMultiplier) + verticalOffset

``````

Yeah, I tried adding a verticalOffset, but it has a strange bug where it never goes down. It rises, then plateaus, then rises again.

[editline]4th October 2013[/editline]

Well, now that I think about it, it makes sense why that’s happening. I’m using SetVelocity() for this:
[lua]
function ENT:Think()
local phys = self:GetPhysicsObject()
if IsValid(phys) then
local oscillate = amp * math.sin(CurTime())

``````	phys:SetVelocity( Vector(0,0, oscillate) )
end
``````

end
[/lua]

-snip, ninja’d by your edit –

I thought the number given by the equation was the point you wanted your object at, I didn’t realise you were using a physical prop and setting the velocity.
You will need to adjust that number based on the current distance from that point, something like this (untested, idea only):

[lua]function ENT:Think()
local phys = self:GetPhysicsObject()
if IsValid(phys) then
local oscillate = amp * math.sin(CurTime()) --Assuming amp is defined elsewhere, it certainly isn’t defined here
local curZ = self:GetPos().z
local dif = curZ-oscillate
–multiply dif by some magic numbers, the props mass, etc
phys:SetVelocity( Vector(0,0, dif) )
end
end[/lua]

Still though, I can’t clamp it and adding an offset would have constant upward velocity. Setting the position in a think hook looks really bad too.

See my edit above

[editline]4th October 2013[/editline]

One other possibility, depending on what you are using the entity for, is overriding ENT.PhysicsSimulate

There’s got to be an easier way to do this. The z difference seems right, but I just don’t know how I should apply it to velocity. If i’m using trig, I want to keep it all math, it seems kind of pointless to use conditional statements at this point. Thanks for your help though I think i’m getting closer.

What do you need this for anyway? Does it really have to be a physics object? If that’s going to be a collectible item with a hovering effect, it’d be so much simpler not to use physics at all and then just setting the position manually.

If you really need to set the velocity of the object and not the position then you can use the derivative of the position:

``````
-- local pos = A*sin(w*CurTime())
local vel = w*A*cos(w*CurTime())

``````

But you are really better off just setting position manually and not using physics.

I don’t know if this helps you or not, but in this video I do something similar with the helper arrows ( rendered-client-side saving the server from having to manage physics or anything ). Instead of physics being active, I attach them to the position of the entity they are helping you find. Then, I adjust the z value from way up in the sky to the object ( all mathematically ), then I use a sin wave to make them bounce up and down while adjusting the yaw to make them spin. If the original object moves, they move with it.

This may look “cleaner” for you; but then again I’m not exactly sure what the purpose is for…

I finished it, now the trough of the wave touches the ground and the amplitude adjusts the height. Thanks for the help everyone.

[lua]
local amp = 60
local speed = 2

function ENT:Think()
local maxs = self:OBBMaxs()
local mins = self:OBBMins()
local height = maxs.Z - mins.Z

``````minheight = 150 - amp - height * .8

local pos = amp * math.sin(speed * CurTime()) - minheight
-- local vel = speed * amp * math.cos(speed * CurTime())

local oscillate = self:GetPos()
oscillate.z = pos

self:SetPos( oscillate )
``````

end
[/lua]