Still have questions? Join our Discord server and get real time help.
0

# How to convert angular velocity to linear velocity?

y3_th 176
5 months ago

I have a BasePart with zero friction that I want to inherit the velocity of the BaseParts beneath it. When it comes to linear velocity, all I have to do is add the velocities of the BaseParts, then add whatever additional velocity I want on top of it in order to achieve my goal.

function FixedUpdate(_, deltaTime) --connected to RunService.Stepped
local baseVelocity = Vector3.new()
for _, part in pairs(GroundedParts) do
if part.CanCollide then
baseVelocity = baseVelocity + part.Velocity --there could be a better way to handle velocity by getting the average of all of the velocities but i'm too lazy to do that right now
end
end

local additionalVelocity = Vector3.new(10, 0, 0)

Movement.Velocity = FinalVelocity --Movement is a BodyVelocity parented to the Part
end


I can also do the same thing with angular velocity and rotations, although I use a BodyGyro instead of a BodyAngularVelocity to lock the X and Z axes of rotation and make it easier to make the part face at an angle.

function FixedUpdate(_, deltaTime) --same function as before except I removed all of the unnecessary parts so this is easier on the eyes I guess
local baseRotVelocity = Vector3.new()
for _, part in pairs(GroundedParts) do
if part.CanCollide then
baseRotVelocity  = baseRotVelocity + part.RotVelocity
end
end

FinalRotation = FinalRotation * cfa(0, baseRotVelocity.Y * deltaTime, 0)
Rotation.CFrame = FinalRotation
end


However, I face an issue when trying to convert the angular velocity into linear velocity. No matter what I try, the rotation always seems slower or faster than the linear velocity, destroying the effect. The only thing I've seem to have gotten correct is how to calculate the direction of the linear velocity, which is perpendicular to the vector between the part that inherits the angular velocity and the part that has the angular velocity.

local function perpendicular(v)
return Vector3.new(v.Z, 0, -v.X) --roblox apparently has a "right-handed" cartesian coordinate system so i have to do this which is just a negated form of Vector3.new(-v.Z, 0, v.X)
end

local radius     = ((Character.Position - part.Position) * Vector3.new(1, 0, 1)).Unit
local tangent    = perpendicular(radius).Unit --there could be a better way to do this using the cross product between the y axis and the radius but i'm just going to leave it like this for now


How am I supposed to calculate the magnitude to multiply the direction by? I know that it somehow involves the angular velocity itself (which is why nothing spins when a part has an angular velocity of 0, 0, 0), but what else should I throw in there, and why?

NOTE: sorry for the bad grammar it's almost 8 pm

0
use a camshaft Fifkee 1956 — 5mo
0
that's an oddly specific problem, what exactly are you trying to achieve with this Elyzzia 474 — 5mo
0
just thought of something to answer this problem y3_th 176 — 5mo

0
y3_th 176
5 months ago
Edited 5 months ago

# Preface

It seems that I was over-complicating this question for anyone to understand, so I've figured out a solution and posted it here. Converting angular velocity to linear velocity was actually easier than I thought.

# Prerequisites

• An understanding of the formula for the length of an arc (length = angle * radius)
• A way to get a perpendicular vector in two-dimensional space

# Explanation

In order to convert angular velocity into linear velocity, we must first get the direction of the linear velocity, which is perpendicular to the distance between the part we want to apply the angular velocity to and the part with the angular velocity.

--just imagine that part2 is the part we want to apply the velocity to and part1 is the part that has the velocity
local function perpendicular(v)
return Vector3.new(v.Z, 0, -v.X)
end

local radius     = (part2.Position - part1.Position) * Vector3.new(1, 0, 1)
local tangent    = perpendicular(radius).Unit --this is the direction that we want the linear velocity to go in


Now that we have the direction of the linear velocity, we need to find the magnitude to multiply it by. Fortunately, the formula for the length of an arc is helpful here. We can treat the linear velocity as a line tangent to a circle that has a magnitude equivalent to the length of an arc with a central angle equivalent to the angular velocity on the Y axis.

local radius     = (part2.Position - part1.Position) * Vector3.new(1, 0, 1)
local tangent    = perpendicular(radius).Unit --this is the direction that we want the linear velocity to go in
local magnitude  = radius.Magnitude * part.RotVelocity.Y --this is the length of the arc, multiplying the radius by theta, which is the part's rotational velocity on the y axis


All we have to do now is to multiply the magnitude by the direction, which gives us what I think is a nice and clean solution.

baseVelocity = baseVelocity + magnitude * tangent


# Result

Here's how it turned out.

It's funny how I spent a week trying to figure this out before going to ScriptingHelpers and then thought of a solution just a few hours after waking up the next day.

0
Oddly enough I sometimes go to bed thinking of a problem and literally wake up with the answer the next day. Sometimes the best thing to do is to take a break from it for a while, otherwise you could end up causing more harm than good to your code. SteelMettle1 268 — 5mo