So I really only have an example, I'm not the math guy, but you can use radians (aka radius)
that deals with measurements of a circle. You can use CFrame.Angles to return a rotation with 3 axis (axes) in radians. So if Pi is half a rotation in radians, then 2*Pi = full circle (360) etc. Hopefully this can help you some...
local Point = CFrame.new(0,10,0)
local Offset = CFrame.new(0,0,10)
local Object = Instance.new("Part",workspace)
Object.Anchored = true
while true do
for i = 1,360 do
Object.CFrame = Point * CFrame.Angles(0,math.rad(i),0) * Offset
wait()
end
end
Apologies for the long post, but this is from BlueTaslem regarding rotation around a single axis part (not world axis)...
That means in order to turn the part, we'll need to be using CFrame.Angles, probably CFrame.new(0, spin, 0) for some spin. So the question is how to determine spin?
We can determine a direction to the target like so:
local direction = target - brick.Position
This has an x and a z (we don't care about the y since that's what we're rotating around) that we need to turn into an angle. When you need to convert normal coordinates into angles, you'll almost always use math.atan2:
local spin = math.atan2(direction.x, direction.z) + math.pi
I cannot explain exactly why that is the right formula, it's just what works. I would have expected it to just be (z, x) but that doesn't work for some reason -- ROBLOX must have a weird way they've made the matrices work out in CFrames.
Then, the part just needs to be turned using that:
1 brick.CFrame = CFrame.new(brick.Position) * CFrame.Angles(0, spin, 0)
Relative Spinning:
brick.CFrame * CFrame.Angles(0, spin, 0) won't work; since * CFrame.Angles spins by an amount, it's only correct when brick starts facing the "0" direction -- thus CFrame.new(brick.Position).
This is a bit of a problem for making it more general, so we should fix that.
There are two ways to go about this.
Calculate the angle difference and multiply by that
Calculate x and z in object space.
While both work for the simple case, 2 will work much better when we generalize.
It's pretty simple to accomplish that. Just compute direction in object space:
local direction = brick.CFrame:pointToObjectSpace( target )
Since this is a relative angle, we do in fact want to use this now:
1 local spin = math.atan2(direction.x, direction.z) + math.pi
2 brick.CFrame = brick.CFrame * CFrame.Angles(0, spin, 0)
Done!
And in fact, now this works no matter how brick is rotated -- we are no longer restricted to just rotating around the (world's) y axis! It's now around the top surface of brick!
1 comment
Something else I’ve seen, is using hinges and bodyforce...I’m still researching myself.