## [SOLVED] Bezier Curves, how to trace a line?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
unixfreak
Citizen
Posts: 55
Joined: Thu Oct 15, 2015 6:25 am
Location: Bristol, UK
Contact:

### Re: Bezier Curves, how to trace a line?

MasterLee wrote:
Fri Apr 21, 2017 6:21 am
Read the following post it covers the problem
https://love2d.org/forums/viewtopic.php ... me#p210511
I'm fully aware of how that can cause problems in some use cases, but it isn't important here. The i value is only being used to remove that index from the list, it's not referenced anywhere else.

zorg
Party member
Posts: 1898
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

### Re: Bezier Curves, how to trace a line?

unixfreak wrote:
Fri Apr 21, 2017 6:48 am
MasterLee wrote:
Fri Apr 21, 2017 6:21 am
Read the following post it covers the problem
https://love2d.org/forums/viewtopic.php ... me#p210511
I'm fully aware of how that can cause problems in some use cases, but it isn't important here. The i value is only being used to remove that index from the list, it's not referenced anywhere else.
But it is referenced, by the ipairs iterator. You are basically pulling elements out under the iterator, which also moves all indices back by one, making it skip entries.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

unixfreak
Citizen
Posts: 55
Joined: Thu Oct 15, 2015 6:25 am
Location: Bristol, UK
Contact:

### Re: Bezier Curves, how to trace a line?

zorg wrote:
Fri Apr 21, 2017 7:37 am
But it is referenced, by the ipairs iterator. You are basically pulling elements out under the iterator, which also moves all indices back by one, making it skip entries.
Then i suppose it must be good practice to iterate over all tables backwards where items are added/removed in a loop every time? There isn't a visible problem as it is, but looking closer now i can see what problem that could cause.

unixfreak
Citizen
Posts: 55
Joined: Thu Oct 15, 2015 6:25 am
Location: Bristol, UK
Contact:

### Re: Bezier Curves, how to trace a line?

On the topix of bezier curves,
I tried to look through Ref's example, where the car moves around the track, although i can't work out what is actually going on in the code to rotate the sprite in the correct direction of movement.

I do see this on the wiki:
https://love2d.org/wiki/BezierCurve:getDerivative
This function can be used to rotate sprites moving along a curve in the direction of the movement and compute the direction perpendicular to the curve at some parameter t.
However i'm not sure how to utilise that to rotate a sprite. Does anyone have an example of this function?
How would you use it? It returns userdata as "BezierCurve", but plotting/drawing it doesn't explain much of what it is doing.

raidho36
Party member
Posts: 1516
Joined: Mon Jun 17, 2013 12:00 pm

### Re: Bezier Curves, how to trace a line?

From basic math knowledge, derivative of a function is another function, which value equals to tangent of original function curve at any given point. It can be interpreted as its direction in that point. Mathematically defined as f'(x) = Δx / Δf, i.e. ratio of step length to step value change - its tangent.

So you compute a derivative of the curve, and you get another curve that has original curve's direction in it. When you draw a sprite, you sample its position from original curve, and rotation from derivative curve. I've never used it, so you may need to pass it through arc tangent function to get meaningful angle.
Attachments
315px-Derivative_of_a_function.svg.png (23.4 KiB) Viewed 833 times

unixfreak
Citizen
Posts: 55
Joined: Thu Oct 15, 2015 6:25 am
Location: Bristol, UK
Contact:

### Re: Bezier Curves, how to trace a line?

My maths knowledge isn't too great, but that makes things more understandable. I have just been fiddling around with math.atan2 in an attempt to rotate a sprite along the derivative curve, but can't seem to get it to work right.

I put together a small love file with relevant code of what i am trying to do here.
The sprite is rotating, but i must be setting something wrong, as it is inaccurate.

The derivatives are drawn here, but end up far off the screen in most cases.
Basically, right click somewhere, then left click somewhere else. Hopefully this should make sense of what i'm trying to do.
bezier_test.love
Also the code, to save having to unzip it all.

Code: Select all

missiles = {}
missiles.launched = {}
missiles.icbm = love.graphics.newImage("icbm.png")

target = {
x = love.graphics.getWidth()/2,
y = love.graphics.getHeight()/2
}

function ripairs(t)
--same as ipairs, but itterate from last to first
local function ripairs_it(t,i)
i=i-1
local v=t[i]
if v==nil then return v end
return i,v
end
return ripairs_it, t, #t+1
end

function love.mousepressed(x,y,button)
--left click to launch a missile
if button == 1 then
end

--right click to set a target
if button == 2 then
target.x = x
target.y = y
end

end

local ax = x
local ay = y
local tx = target.x
local ty = target.y

--values for the bezier curve
local bx,by
if ax < tx then
bx = ax + (tx - ax)
else
bx = tx+ (ax -tx)
end

if ay < ty then
by = 0
else
by = 0
end

local trajectory = love.math.newBezierCurve(
tx,ty,bx,by,ax,ay
)

table.insert(missiles.launched, {
x = ax, -- missile source
y = ay,

mx = ax, -- missile projectile
my = ay,

tx = tx, -- missile destination
ty = ty,

dx = 0, -- missile derivative
dy = 0,

t = 0, -- missile time / distance

trajectory = trajectory, -- the bezier curves
derivative = trajectory:getDerivative(),

angle = 0, -- angle of missile sprite
o = 200, --opacity
speed = 0.25, -- speed used for "t"
info = false, -- hud overlay
weapon = "ICBM" -- weapon type
})

--sound.playfx("launch")

end

function love.update(dt)
for i, missile in ripairs(missiles.launched) do

missile.t = missile.t+missile.speed*dt

if missile.t > 1 then
--missile reaches destination
table.remove(missiles.launched,i)
else

--evaluate missile trajectory
missile.mx,missile.my = missile.trajectory:evaluate(missile.t)

--evaluate missile derivative trajectory
missile.dx,missile.dy = missile.derivative:evaluate(missile.t)

--find the difference in angle (draw missile sprite using this)
missile.angle = math.atan2(missile.mx-missile.dx, missile.my-missile.dy)

end
end
end

function love.draw()
for i, missile in ipairs(missiles.launched) do

love.graphics.setColor(0,255,0,200)
love.graphics.circle("fill",missile.mx,missile.my,10)

--draw incremental beacons across trajectory
for i=0,10 do
local x,y = missile.trajectory:evaluate(i/10)
local size = 5
love.graphics.rectangle("fill",x-size/2,y-size/2,size,size)

local x,y = missile.derivative:evaluate(i/10)
local size = 5
love.graphics.rectangle("fill",x-size/2,y-size/2,size,size)
end

--the bezier curve (trajectory)
love.graphics.setColor(
255,0,0,missile.o
)
love.graphics.line(missile.trajectory:render())

--derivative curve
love.graphics.line(missile.derivative:render())

--position of point/time on the bezier curves
love.graphics.circle("fill",missile.mx,missile.my,5)
love.graphics.circle("fill",missile.dx,missile.dy,5)

love.graphics.line(missile.mx,missile.my,missile.dx,missile.dy)

love.graphics.setColor(
255,155,0,255
)
love.graphics.draw(missiles.icbm, missile.mx,missile.my, missile.angle, 1,1,missiles.icbm:getWidth()/2,missiles.icbm:getHeight()/2)

end

love.graphics.setColor(255,255,255,255)
love.graphics.print("right click to select launch site\nleft click to launch missile",10,10)
end



raidho36
Party member
Posts: 1516
Joined: Mon Jun 17, 2013 12:00 pm

### Re: Bezier Curves, how to trace a line?

Yes, you should just feed it derivative coordinates. I had to offset resulting angle because your sprite is rotated.
Attachments
bezier_test.love

unixfreak
Citizen
Posts: 55
Joined: Thu Oct 15, 2015 6:25 am
Location: Bristol, UK
Contact:

### Re: Bezier Curves, how to trace a line?

raidho36 wrote:
Sat Apr 22, 2017 8:55 pm
Yes, you should just feed it derivative coordinates. I had to offset resulting angle because your sprite is rotated.
I had a feeling i was plotting the derivative wrongly, but seems that was not the case. Many thanks! That works perfectly.
Thank you everyone for the suggestions / examples. I think i understand this alot better now.

alberto_lara
Party member
Posts: 315
Joined: Wed Oct 30, 2013 8:59 pm

### Re: [SOLVED] Bezier Curves, how to trace a line?

I know it's already solved but maybe you could try a tweening library the next time, flux is a nice option
LÖVE Projects: GOOi, Süsse, Dyzön and Katsudö
Thanks for taking the time and read this

unixfreak
Citizen
Posts: 55
Joined: Thu Oct 15, 2015 6:25 am
Location: Bristol, UK
Contact:

### Re: [SOLVED] Bezier Curves, how to trace a line?

alberto_lara wrote:
Sat Apr 22, 2017 10:35 pm
I know it's already solved but maybe you could try a tweening library the next time, flux is a nice option
Yes, that's always the easiest/fastest approach, but i've never been keen on using libraries for making small demos/games. Mostly because i'd like to use Love2D as a learning experience, which can be carried across other programming languages with the logic. A complicated library mostly does everything without teaching you much of how it actually works. Just my opinion though.

### Who is online

Users browsing this forum: Google [Bot] and 11 guests