# 3D Pendulum Script

With this code I have created a pendulum that works along the X and Y axis, how would I go about making this work for the Z axis as well?

``````local Bob = workspace.Bob
local Origin = workspace.Origin

local Length = (Origin.Position - Bob.Position).Magnitude

game["Run Service"].Heartbeat:Connect(function(dT)
theta = theta + aVelocity

local XArc = Length * math.sin(theta)
local YArc = Length * math.cos(theta)

Bob.Position = Origin.Position + Vector3.new(XArc, -YArc, 0)
end)``````

Iâm not really too great with trigonometry but surely youâd use tangent to get the Z axis?

``````local ZArc = Length * math.tan(theta)
``````

By âworking on the Z axisâ do you mean you want it to work regardless of how the object is oriented?

``````...
Bob.CFrame = Origin.CFrame * CFrame.new(XArc, -YArc, 0)
...
``````
1 Like

Have you confused a pendulum with orbiting? Because what your code produces is object âBobâ orbiting around object âOriginâ in a full circle.

A pendulum is essentially a swinging object which moves side to side. What you should use here is a sine wave which you give `tick()` as an argument to provide a continuous range from -1 to 1.

From this, you can continuously update Bobâs CFrame using Originâs position, taking into account the originâs rotation as well and applying an offset which is half the length of the pendulum.

``````game:GetService("RunService").Heartbeat:Connect(function()
local swing = math.sin(tick())

Bob.CFrame = (CFrame.new(Origin.Position) * CFrame.Angles(0, math.rad(Origin.Orientation.Y), swing) * CFrame.new(0, -Bob.Size.Y/2, 0))
end)
``````

This produces the following as a result and allows for rotating the origin and updating accordingly:

7 Likes

thanks, that is the type of behavior I am looking for.

Another question: how would I increase the range and allow the bob to swing to higher positions?

Apply a multiplier to the sine wave. For example if you double it, youâll notice it will swing much higher.

``````local swing = math.sin(tick()) * 2
``````
1 Like