Hello guys, I’m trying to learn beziers. But most hard thing I met is offsetting N studs from some point.
Because bezier has variying lengths between 2 point every time, I tried to make code which will constantly check offset length until wanted offest with treshhold achieved
I tried to use this code, modified it a lot, but sadly, for now best what I have got is increse of distance from desired dot.
Can someone help me to fix my code, so it will be able to calculate approximate offset from dot on bezier?
local function CreateCurve(Dots, Mode, Time, Params)
if Mode == "Length" then
local BezierCurve = {}
Time = Time or 1
if Time <= 0 then error("INVALID TIME") end
local i = 0
while i <= Params do
local Value = i/Params * Time
local Lerps = table.clone(Dots)
if Time == math.huge then error("Inf asquared") end
while #Lerps > 1 do
for a = 1, #Lerps-1, 1 do
Lerps[a] = Vector3.new(Lerps[a].X * (1 - Value) + Lerps[a+1].X * Value, 0, Lerps[a].Z * (1 - Value) + Lerps[a+1].Z * Value)
end
Lerps[#Lerps] = nil
end
table.insert(BezierCurve, Lerps[1])
i += 1
end
local BezierLength = 0
for i = 1, #BezierCurve - 1, 1 do
BezierLength += (BezierCurve[i + 1] - BezierCurve[i]).Magnitude
end
return BezierLength
elseif Mode == "Dot" then
local BezierCurve = {}
local Lerps = table.clone(Dots)
while #Lerps > 1 do
for a = 1, #Lerps-1, 1 do
Lerps[a] = Vector3.new(Lerps[a].X * (1 - Time) + Lerps[a+1].X * Time, 0, Lerps[a].Z * (1 - Time) + Lerps[a+1].Z * Time)
end
Lerps[#Lerps] = nil
end
return Lerps[1]
elseif Mode == "Offset" then
local BezierSize = Params[1] or CreateCurve(Dots, "Length", nil, 100)
local StartLengthToDot = CreateCurve(Dots, "Length", Time, 25)
local BaseOffset = Params[2]
--local LengthToDot = StartLengthToDot
local Dot
local Breakage = 100
local CheckTime = Time
--local AverageLength = LengthToDot / Time
local Offset = BaseOffset
local Variativity = 1
warn(BezierSize)
--warn(LengthToDot)
repeat
local CurOffset = BaseOffset * Variativity
CheckTime = (StartLengthToDot + CurOffset) / BezierSize --0.4
local LengthToDot = CreateCurve(Dots, "Length", CheckTime, 25)
local Marker = Instance.new("Part")
Marker.Anchored = true
Marker.Size = Vector3.new(0.15, 0.15, 0.15)
Marker.Position = CreateCurve(Dots, "Dot", CheckTime)
Marker.Color = Color3.fromRGB(0, 255 * ((100 - Breakage) / 100), 255 * ((100 - Breakage) / 100))
Marker.Parent = workspace
Offset = LengthToDot - StartLengthToDot
Variativity = BaseOffset / Offset
warn(Variativity, CheckTime)
--warn("\nCheck time: " .. tostring(CheckTime) .. "\nLengthToDot is " .. tostring(LengthToDot) .. "\nCurOffset is " .. tostring(CurOffset) .. "\nOffset is " .. tostring(Offset))
Breakage -= 1
if Breakage <= 0 then
error("Too many iterations")
end
task.wait(0.5)
until math.abs(Offset) < 0.01
return CreateCurve(Dots, "Dot", CheckTime)
end
end
local Points = {
Vector3.new(0, 0, 0),
Vector3.new(50, 0, 50),
--Vector3.new(0, 0, 75),
--Vector3.new(-50, 0, -100),
Vector3.new(0, 0, 100),
}
for i = 1, 1000, 1 do
local Dot = CreateCurve(Points, "Dot", i/1000)
local Marker = Instance.new("Part")
Marker.Anchored = true
Marker.Size = Vector3.new(0.1, 0.1, 0.1)
Marker.Position = Dot
Marker.Color = Color3.fromRGB(255, 0, 0)
Marker.Parent = workspace
end
local Marker = Instance.new("Part")
Marker.Anchored = true
Marker.Size = Vector3.new(0.3, 0.3, 0.3)
Marker.Position = CreateCurve(Points, "Dot", 0.5)
Marker.Color = Color3.fromRGB(0, 0, 255)
Marker.Parent = workspace
Marker = Marker:Clone()
Marker.Position = CreateCurve(Points, "Offset", 0.5, {CreateCurve(Points, "Length", 1, 100), -10})
Marker.Color = Color3.fromRGB(0, 255, 0)
Marker.Parent = workspace
CreateCurve(Points, "Length", nil, 100)