How do I apply rotation to a sphere to make it roll in accordance to it's change in displacement?

Hello, I’m trying to “roll” a sphere in accordance to it’s change in displacement with CFrame.
Here’s what I have so far:

local circumference = sphere.Size.Y * math.pi
local lastPos = sphere.CFrame.p
sphere:GetPropertyChangedSignal('Position'):Connect(function()
	local currentPos = sphere.CFrame.p
	local change = currentPos-lastPos
	local changeInRadians = (change / circumference) * math.rad(360)
	local x,y,z = changeInRadians.X,changeInRadians.Y,changeInRadians.Z
	sphere.CFrame = sphere.CFrame * CFrame.Angles(x,y,z)
	lastPos = sphere.CFrame.p
end)

The problem with this is it begins to roll inaccurately when the orientation of other other axis’ are changed. (shown here: https://gyazo.com/87f3964fe5471ac64b00df899ef9a5e4)

1 Like

Is there are reason why you couldn’t of just have a body force applied to it instead of a script?

Yep, it needs to be CFrame; I’m using it to precisely show rolling motion in a transition between two points inside of a viewport frame. I also need to be able to scale up the amount of objects efficiently so hackily putting objects in the workspace with bodyvels and replicating their rotation wouldn’t work either.

2 Likes

To calculate the vector that your object needs to rotate around, first calculate the velocity vector of the object. Next, calculate the normal vector to the ground that the object is actually rolling on. Lastly, calculate the orthogonal vector via cross product. This is the ‘axis of rotation’ for the object. To calculate the rotational velocity of the object accurately, simply convert the linear velocity to rotation velocity via v/r=w

3 Likes

Like jody said, then you can use CFrame.fromAxisAngle( Vector3 v, number r ). v is the orthogonal vector to the surface normal and movement while r is the rotation in radians.

3 Likes