Why do we not have built-in CFrame interpolation functions?

My suggestion for this would simply be an addition to the * operator for CFrames which allow us to multiply a CFrame by a number.

CFrame*Number

For example

MyCFrame*0.5 would be half interpolated between CFrame.new() and MyCFrame

How we could make an interpolate function from this is:

local function Interpolate(CFrame0,CFrame1,t)
    local RelativeCFrame=CFrame0:inverse()*CFrame1--The CFrame such that CFrame0*RelativeCFrame=CFrame1
    local InterpolatedRelativeCFrame=RelativeCFrame*t--Using the operation I'm suggesting
    return CFrame0*InterpolatedRelativeCFrame
end

Here’s about what would go on in the background.

--Handles all errors correctly.
local cf, v3 = CFrame.new, Vector3.new
local components = cf().components
local acos, cos, sin = math.acos, math.cos, math.sin

local function CFrameTimesNumber(c,n)
	local x, y, z, xx, yx, zx, xy, yy, zy, xz, yz, zz = components(c)
	local xxyyzz = xx + yy + zz
	if zz > 0.1^8-1 and xxyyzz < 3-0.1^8 then
		local t = acos((xxyyzz - 1) / 2)*n
		local c, s = cos(t), sin(t)
		local ax, ay, az = yz - zy, zx - xz, xy - yx
		local m = (ax*ax + ay*ay + az*az) ^ 0.5
		local nax, nay, naz = ax/m, ay/m, az/m -- Normalized axis
		return cf(x*n, y*n, z*n, --Position
			t*nax*nax + c, t*nax*nay - naz*s, t*nax*naz + nay*s,
			t*nax*nay + naz*s, t*nay*nay + c, t*nay*naz - nax*s, --Matrix
			t*nax*naz - nay*s, t*nay*naz + nax*s, t*naz*naz + c)
	elseif n > 0.5 then
		local nn = 1 - n
		return c - v3(x*nn, y*nn, z*nn)
	else
		return cf(x*n, y*n, z*n)
	end
end
1 Like

This is such a good idea in general; it can do a lot more than just be used for that.

1 Like

Why not CF:Lerp(CF, N)?

2 Likes

Multiplication/division operators would be more useful, imo.

1 Like

Because a multiplication operation is more useful. It’s more basic therefor it can be used in more places.

1 Like

There is quite a problem with that. How do you multiply a rotation matrix by a number? What would the result of that mean? Using it on something like a quaternion, axis angles or euler angles would make more sense as they use numeric rotation values however rotation matrices use normalized vectors. Trey you should know this, and you should also know that this is why you use axis angles to interpolate cframes.

EDIT: I jumped the gun a bit there. I suppose roblox could do the interpolation properly c-side for us. Not sure how I feel about it though.

This would help a lot of players who have no idea what they’re doing. We’re all using a lot of utility functions to do this right now, and honestly, not everyone can use these because they don’t know they exist.

Along with this, I’d also like some operators on the Color3 and UDim2 values that could be useful, such as scaling.

Jeez, hostile.

First of all, it’s ridiculous to assume I don’t understand all of the mathematics behind what I am suggesting. Obviously it would first convert the matrix of the CFrame into Axis Angle representation and then multiply that by the number, then converting back to the CFrame. The position would lerp between <0,0,0> and CFrame.p. The suggestion that it should be done with euler angles is laughable because it’s so mathematically incorrect.

The intention is to make a faster, more C-sided interpolation which is easy for all users to use.

The reason for not having a specified lerpCFrame function is because in many cases, you want to change the magnitude of the rotation and position by a specified number. This is why it would by *Number.

EDIT: Sorry, didn’t see your edit. Still, use of the multiplication operator is more perfect and useful. I don’t see why allowing for inexperienced users to do cool stuff with CFrame would unsettle you.

2 Likes

After thinking about it for a while, having multiplication work like this would probably be the best way for this to work. ROBLOX pls add.

This suggestion excites me. What would be going on in the background though?

Probably TV-MA rated material.

“My suggestion for this would simply be an addition to the * operator for CFrames which allow us to multiply a CFrame by a number.”

You of all people should understand that this doesn’t work / doesn’t make sense. Sure, it could be made to work for the special case that you’re talking about, but, it wouldn’t work for anything else, and wouldn’t follow the general algebraic rules that you would expect a “*” operator to respect, thus it’s a really bad API. What should exist is simply an interpolation function on CFrames:

CFrameA:Slerp(CFrameB, t)
-- or even
CFrameA:Interpolate(CFrameB, t)

Which uses interpolates via Slerp-ing between the quaternions of the two CFrames. That’s a much better API, and it’s usage would be obvious to anyone with some computer graphics knowledge reading just the name and the arguments of a function. On the other hand, no-one will know what a CFrame x Scalar operator’s actual function is without specifically looking at an example in the documentation.

Also, the operator you propose would probably be slower than a Slerp / Interpolate function, because your operator would have to go through the C-API twice, whereas an interpolate one would only have to go through the C-API once.

What is this math you speak of?

[quote]
You of all people should understand that this doesn’t work / doesn’t make sense. Sure, it could be made to work for the special case that you’re talking about, but, it wouldn’t work for anything else, and wouldn’t follow the general algebraic rules that you would expect a “*” operator to respect, thus it’s a really bad API.[/quote]

I understand this. As you know, a CFrame is a set of two completely different things, a position and a rotation. For the position, a multiplication is correct. For the interpolation of a rotation, ^ is the correct operator to use. Because a single operation was necessary for what I was suggesting, and because the position of a CFrame is easier to understand than the rotation, I thought that the * operator would be the best one to use. You’re right, though. Obviously I don’t build APIs for a living.

Maybe CFrame*Number would result in a scaling of the position, not affecting the rotation. And CFrame^Number would result in a powering of the rotation, not affecting the position.
This is correct and makes sense.

CFrame:Interpolate(CFrame,t) would be awesome, too.

Thanks for the suggestions.
Regardless of what it is or in what form it comes, a built in interpolate function would be really nice for everyone.

Because a multiplication operation is more useful. It’s more basic therefor it can be used in more places.[/quote]