Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How would I use Vector3:Lerp(Vector3, Alpha) for CFrame Rotation?

Asked by 9 years ago

EDIT:[Sorry for not being specific] I am basically rotating a part on the Y axis using the C0 and C1 properties of a motor weld.

I have two parts connected with a motor weld and would like to smoothly rotate the CFrame (Or C0 if you will) using some type of lerp, the wiki stated Vector3:Lerp, but how would I use it in CFrame.Angles? One conductor is CFrame.fromAxisAngle, but I have no idea how to use that. And bodygyro's are out of the picture. If you have any other method, ideas would be appreciated.

Thanks.

EDIT2: This apparently rotates the part way over 360 degrees when it should rotate only 90 as you stated.

local cframe = script.Parent.CFrame -- our starting cframe
local startRotation = 0
local endRotation = 0.5*math.pi

function lerp(start, finish, alpha)
        return start + (finish - start)*alpha
end


function getYRotatedCFrame(cframe, startRotation, endRotation, alpha)
    return cframe*CFrame.Angles(0, lerp(startRotation, endRotation, alpha), 0)
end

for index = 1, 100 do
   script.Parent.CFrame = getYRotatedCFrame(script.Parent.CFrame, startRotation, endRotation, index / 100)
    wait(0.03)
end

EDIT3: the index part of the code should be

for i = 1, 100 do
   script.Parent.CFrame = CFrame.Angles (0,lerp(startRotation, endRotation, i / 100),0) + script.Parent.Position
    wait()
end

making it equal to the angles will give you the exact rotation desired. BTW, I dont see the need for the second function.

Working code:

local startRotation = math.rad(0)
local endRotation = math.rad(90)

function lerp(start, finish, alpha)
        return (finish - start)*alpha
end

for i = 1, 100 do
   script.Parent.CFrame = CFrame.Angles (0,lerp(startRotation, endRotation, i / 100),0) + script.Parent.Position
    wait()
end
0
What exactly do you want to do with it? What are you trying to do? Please be more specific. TurboFusion 1821 — 9y
0
Better? Orlando777 315 — 9y
0
Yes, thank you TurboFusion 1821 — 9y

1 answer

Log in to vote
2
Answered by
Unclear 1776 Moderation Voter
9 years ago

Interpolation in computer science is useful because it allows you to give a certain value between a start value and end value given an alpha between 0 and 1. The value depends on the interpolation function you use.

In this case, you want to use lerp, or linear interpolation. Linear interpolation can be described as the following.

function lerp(start, finish, alpha)
        return start + (finish - start)*alpha
end

When you use the Lerp method in Vector3, it is defined as something similar to the following...

function Vector3:Lerp(finish, alpha)
    -- implicit definition of self being the Vector3 Lerp is applied on
    return Vector3.new(
        lerp(self.x, finish.x, alpha),
        lerp(self.y, finish.y, alpha),
        lerp(self.z, finish.z, alpha)
    )
end

Basically, a linear interpolation on a Vector3 would be just a linear interpolation on all three of its dimensions (x, y, and z).

For a rotation that is just along the object Y axis, you can use CFrame.Angles on the Y axis combined with a single angle value theta. theta will be described in radians, so it should be between 0 and 2pi. In degrees, this can be thought of as being between 0 and 180 degrees. You can freely translate between radians and degrees by using either math.deg or math.rad, respectively.

Once you know your start Y axis rotation in radians and your end Y axis rotation in radians, you can just apply the linear interpolation function that we defined above on that!

Here is a thrown together example of applying our knowledge above...

local cframe = CFrame.new() -- our starting cframe
local startRotation = 0
local endRotation = 0.5*math.pi -- or 90 degrees counterclockwise

function getYRotatedCFrame(cframe, startRotation, endRotation, alpha)
    return cframe*CFrame.Angles(0, lerp(startRotation, endRotation, alpha), 0)
end

for index = 1, 100 do
    local newCFrame = getYRotatedCFrame(cframe, startRotation, endRotation, index / 100)
    -- do something with newCFrame
    wait(0.03)
end
  • You can get even smoother results by doing rotations on the client through a LocalScript and syncing all CFrames by RenderStepped. This will force you to keep track of what alpha is and is a bit of a challenge to figure out if you are just starting out, but it is well worth your time.

  • Note that if you use multiple Euler angle axis, you can get thrown into a bad situation called gimbal lock. Basically, there are certain situations where the rotation will flip 180 degrees. If you are trying to expand this to multiple axis, you should look into slerp, or spherical interpolation. Using slerp will prevent gimbal lock from ever happening, but it is a bit tricky to implement for beginners!

All in all, this is a great example of using knowledge at hand to solve a problem you don't know how to solve. You should be able to conquer any problem if you are good at applying what you already know, so practice doing it and experiment with the code above.

0
Wow, see, people like you make this website actually worth something. Thank you for your time and answer, I will test this later and let you know if it worked in my situation. Orlando777 315 — 9y
0
There's one slight problem with the code, if I use math.rad (Which is easier IMO) and I set it to 1 degree, it rotates to 45 degrees because of the index/100. If you change the 100, the rotation will vary. Orlando777 315 — 9y
0
You divide by 100 because you're doing 100 iterations. alpha varies from 0 to 1, so we are splitting that up into 100 parts. Unclear 1776 — 9y
0
On top of that, using math.rad is risky because you end up not getting things right. I don't see an error, so it's probably on your part. Try testing the code as it is without touching it with a regular Part's CFrame. Unclear 1776 — 9y
View all comments (4 more)
0
I updated the question. It's still not working properly. Orlando777 315 — 9y
0
I figured it out. The error in the code is that you did not specify the addition of the parts existing rotation and position. Therefore continuously adding a percentage of the overall rotation, which would result into a weird rotation and not reaching your desired rotation. Solution is posted in my third edit. Thank you for your help in clearing things up. Orlando777 315 — 9y
0
... I didn't need to specify them. "-- do something with newCFrame" was the part where you were supposed to do that yourself, haha. Unclear 1776 — 9y
0
That's fine though, I'm glad you figured it out. Unclear 1776 — 9y
Ad

Answer this question