Calculate instantaneous Vector3 lookVector at a given point t where 0>=t>1 for Bezier curve

In this tutorial, a library for n points for a bezier curve is provided.

https://developer.roblox.com/en-us/articles/Bezier-curves

How do I find the instantaneous Vector3 lookVector at a given point t where 0>=t>1? I want to make a panoramic by making a scene using the vectors perpendicular to it.

1 Like

I believe you can do some limit calculus estimation to find the perpendicular vector at time t.

Just input t plus a small value to find the position ahead of time t +0.1 then you can get a vector from two points from point t to point t +0.1 seconds.

Edit: Or I believe a better way is to differentiate the formula to by t to get the perpendicular slope.

1 Like

The above solution would probably work fine in most applications. Here’s a way that you can calculate it exactly, if that’s what you need:

What you’re looking for is called the tangent of the curve at a given point, and is equivalent to the derivative of the curve at the given point. Wikipedia has formulas for the 1st and 2nd derivative of a cubic beziér curves, which is the special case of beziér curves that the Roblox wiki talks about:

image

Assuming that you’re working off this function for computing the beziér curve:

function cubicBezier(t, p0, p1, p2, p3)
	local l1 = lerp(p0, p1, t)
	local l2 = lerp(p1, p2, t)
	local l3 = lerp(p2, p3, t)
	local a = lerp(l1, l2, t)
	local b = lerp(l2, l3, t)
	local cubic = lerp(a, b, t)
	return cubic
end

You can compute the tangent of the beziér curve by adapting the above formula:

function cubicBezierTangent(t, p0, p1, p2, p3)
	--From https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves
	return
		3 * (1 - t)^2 * (p1 - p0)
		+ 6 * (1 - t) * t * (p2 - p1)
		+ 3 * t^2 * (p3 - p2)
end

Testing it gives this result:

… which looks about right.

Here's the test code I used:

function lerp(a, b, t)
	return a + (b - a) * t
end

function cubicBezier(t, p0, p1, p2, p3)
	local l1 = lerp(p0, p1, t)
	local l2 = lerp(p1, p2, t)
	local l3 = lerp(p2, p3, t)
	local a = lerp(l1, l2, t)
	local b = lerp(l2, l3, t)
	local cubic = lerp(a, b, t)
	return cubic
end

function cubicBezierTangent(t, p0, p1, p2, p3)
	return
		3 * (1 - t)^2 * (p1 - p0)
		+ 6 * (1 - t) * t * (p2 - p1)
		+ 3 * t^2 * (p3 - p2)
end

local p0, p1, p2, p3 =
	Vector3.new(),
	Vector3.new(0, 20, 0),
	Vector3.new(20, 10, 0),
	Vector3.new(25, 0, 0)

for t = 0, 1, 1/50 do
	local p = Instance.new("Part")
	p.Anchored = true
	p.Size = Vector3.new(1, 1, 1) * 0.1
	p.CFrame = CFrame.new( cubicBezier(t, p0, p1, p2, p3) )
	p.Color = Color3.fromRGB(255, 0, 0)
	p.Parent = game.Workspace
	
	local tangent = p:Clone()
	tangent.Size = Vector3.new(0, 0, .5)
	tangent.CFrame = CFrame.new( p.Position, p.Position + cubicBezierTangent(t, p0, p1, p2, p3) )	
	tangent.CFrame += tangent.CFrame.LookVector * tangent.Size.Z * 0.5
	tangent.Color = Color3.fromRGB(0, 55, 255)
	tangent.Parent = game.Workspace
end
2 Likes