Smooth curve with 2 points

How is the function supposed to know what kind of curve you want?


There are an infinite amount of options, every smooth curve from points function takes atleast 3 points to know what you want.

1 Like

pretty sure you would always need a third point to tell how intense the curve is going to be if its 2 points then its just a line m8.

How can I create a smooth L curve by calculating the position of the third point?

By giving the three points to a bezier curve function?

If you mean “how do I calculate the third point” then it depends on where you want the third point to be:

What direction do you want the L curve? How smooth should it be? etc…

I want the points to form a L shape

I learned a lot from this module to create tween bezier curves with 3 points dinamycally, to make a part travel all the points
Bezier Curve Creator

You can generate a right angle triangle between the points, but then still you don’t know which side…

test the 3, I made the arguments easier to read

Lerp

local function Lerp(Start, End, Time)
	return Start + (End - Start) * Time
end

local Start = Vector2.new(0, 0) -- top left
local End = Vector2.new(1, 1) -- bottom right

for Time=0, 1, 0.01 do
	print(Lerp(Start, End, Time))
end

Quadratic

local function QuadraticBezier(Time, Start, Middle, End)
	return (1 - Time)^2 * Start + 2 * (1 - Time) * Time * Middle + Time^2 * End
end

local Start = Vector2.new(0, 0) -- top left
local Middle = Vector2.new(1, 0) -- top right I think
local End = Vector2.new(1, 1) -- bottom right

for Time=0, 1, 0.01 do
	print(QuadraticBezier(Time, Start, Middle, End))
end

Cubic

local function CubicBezier(Time, Start, Middle1, Middle2, End)
	return (1 - Time)^3*Start + 3*(1 - Time)^2*Time*Middle1 + 3*(1 - Time)*Time^2*Middle2 + Time^3*End
end

local Start = Vector2.new(0, 0) -- top left
local Middle1 = Vector2.new(1, 0) -- top right
local Middle2 = Vector2.new(0, 1) -- bottom left
local End = Vector2.new(1, 1) -- bottom right

for Time=0, 1, 0.01 do
	print(CubicBezier(Time, Start, Middle1, Middle2, End))
end

You must have at least 1 extra point.

What you linked needs more than 2 points.


What you posted also needs more than 2 points (except for the lerp but that isn’t a curve).

Also Artzified’s link

has the code you posted


This has already been said.


Please read the post and it’s replies to see whether your otherwise useful replies are needed.

1 Like

Here’s some pseudo code to generate the third point

  1. Get the center point between the 2 points (green)
  2. Get the distance between the 2 points (diameter of the black circle)
  3. Get the angle from the center point of one of the 2 points (yellow angle)
    (the orangle line is 0°)
  4. Add 90° to the angle (pink angle)
  5. Generate the position of the third point using the new angle (red point)

image

Depending on which point you calculate the angle from and whether you add or subtract 90° you can choose which of the 2 red points you want.

Thats what I said… 3 points… I support that having 3 points its needed…
3 points and even more its helpful

The link you posted is helpful, but it isn’t what Artzified asked for, he already has code to generate a bezier curve

He just needs an alternative to bezier curves that doesn’t need 3 points (doesn’t exist), or a way to generate the third point.

yeah… if using less than 3 points its not possible, and not knowing how to generate the point 3, I just provided a module to check to understand the using the 3 points, documentation never harms… ¬¬

i’m having trouble getting the angle. is this correct?

local angle = (p1 - centerPoint).Unit:Dot(p2)

which one?

I meant something more like this

local p1Offset = p1 - centerPoint
local angle = math.atan2(p1Offset.Y, p1Offset.X)
    + math.rad(90) -- add the 90° right away, no need to wait

Then generate the new point like so

local radius = diameter / 2
local thirdPoint = Vector2.new( math.cos(angle) * radius, math.sin(angle) * radius )

It doesn’t seem to work when i visualize it in 3d space

local diameter = (p1.Position-p2.Position).Magnitude
local centerPoint = (p1.Position-p2.Position) / 2

local offset = p1.Position - centerPoint

local angle = math.atan2(offset.Y, offset.X) + math.rad(90)

local radius = diameter/2
local thirdPoint = Vector3.new(math.cos(angle) * radius, math.sin(angle) * radius)

No in 3d it wouldn’t work, because then you have an infinite amount of red points (the red circle)

What do the 2 points represent and why do you need an L shaped angle between them?

those are the waypoints.
I am currently making a car AI which works well but, when doing a long short turn, it collides with with the sidewalk because its directly moving to the target


the yellow line is the current behavior
the green line is the expected behavior

Are you using Roblox pathfinding or your own?

If you use Roblox’s you should force it to follow the road by using PathfindingModifiers or by calling the pathfinding method multiple times.

If you use your own you should place the points to pathfind over in the center of each turn so that it doesn’t take sharp corners.


Also Spline Interpolation might help, it also uses more than 2 points but it goes through every point you give it.

So you can just use the previous and next point in the path as the 3rd and 4th points.

2 Likes