lerping - how to continue past target position

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.
Post Reply
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

lerping - how to continue past target position

Post by Vimm »

so I have this code

Code: Select all

function love.load()
	randomX = love.math.random(0, (love.window.getWidth()))
	randomY = love.math.random(0, (love.window.getHeight()))
	
	ballX = love.window.getWidth()/2
	ballY = love.window.getHeight()/2
end

function love.update(dt)
	ballX = lerp(ballX, randomX, (2 * dt))
	ballY = lerp(ballY, randomY, (2 * dt))
end

function love.draw()
	love.graphics.rectangle("fill", ballX, ballY, 8,8)
end

function lerp(initial_value, target_value, speed)
	local result = (1-speed) * initial_value + speed*target_value
	return result
end
which is making my squares move towards a random position. Now what I want to make it do is, continue past that point and when it hits the end of the screen, bounce off. I can most likely manage to bounce part but I can't figure out how to make it keep moving after it reaches the target value. I imagine velocity variables are needed but I'm not smart enough for that.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: lerping - how to continue past target position

Post by zorg »

The issue with lerping between two values is exactly this, you're parametrically adjusting the ratio between two values, and you can't "go outside" that range.

Another thing is that this way, you're not storing any velocity value. Neither per-component (however you'd represent it, like vx, vy or dx, dy), nor as a vector (with direction, and magnitude), so you can't easily calculate where the ball should be after x time; in short, lerping can't extrapolate.

Solution could be to have one or the other velocity variables, and use that when updating the ball's position, as for that random point selection, just set the direction so the ball intersects it; i'm assuming you aren't using it for anything else, only for giving a starting direction.

Helpful algorithms would be the conversions between cartesian and polar coordinate systems.
Me and my stuff :3True 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.
User avatar
pgimeno
Party member
Posts: 3548
Joined: Sun Oct 18, 2015 2:58 pm

Re: lerping - how to continue past target position

Post by pgimeno »

As I mentioned in a different thread, that's actually not LERPing (linear interpolation); that's an exponential approach (a geometric succession) with an asymptote in the target position, meaning it will approximate it more and more and more but never go past it. It's not how you're supposed to use the lerp function usually.

Your approach isn't the most adequate for a bouncing ball. Rather than setting targets, you should set velocities. It's not that hard. Basically, the velocity is the amount of pixels in each axis that the ball travels each second. So, every frame you add the velocity times the frame time (dt) to the position, and that's all.

Bouncing consists of changing the sign of one of the velocity axes.

Something like this (note: you need to keep your brain engaged to use it)

Code: Select all

-- Initialize the position in some way
ball.x = ...
ball.y = ...

-- Initialize the velocity in some way, for example a fixed speed at a random direction
local speed = 20 -- that's 20 pixels per second
do
  local angle = 2*math.pi*love.math.random() -- choose a random direction
  ball.vx = cos(angle) * speed
  ball.vy = sin(angle) * speed
end

-- Do something like this when you need to update
ball.x = ball.x + ball.vx * dt
ball.y = ball.y + ball.vy * dt

-- Do something like this when you detect bouncing on a horizontal wall
ball.vy = -ball.vy

-- Do something like this when you detect bouncing on a vertical wall
ball.vx = -ball.vx
You will typically also need to correct the position of the ball when it bounces, because when you detect the collision, it's already past the wall. That's called collision resolution. If you have trouble with that, maybe you could use a library that handles it.

Edited to fix typo
Last edited by pgimeno on Fri Apr 15, 2016 10:00 pm, edited 1 time in total.
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: lerping - how to continue past target position

Post by Vimm »

pgimeno wrote:As I mentioned in a different thread, that's actually not LERPing (linear interpolation); that's an exponential approach (a geometric successon) with an asymptote in the target position, meaning it will approximate it more and more and more but never go past it. It's not how you're supposed to use the lerp function usually.

Your approach isn't the most adequate for a bouncing ball. Rather than setting targets, you should set velocities. It's not that hard. Basically, the velocity is the amount of pixels in each axis that the ball travels each second. So, every frame you add the velocity times the frame time (dt) to the position, and that's all.

Bouncing consists of changing the sign of one of the velocity axes.

Something like this (note: you need to keep your brain engaged to use it)

Code: Select all

-- Initialize the position in some way
ball.x = ...
ball.y = ...

-- Initialize the velocity in some way, for example a fixed speed at a random direction
local speed = 20 -- that's 20 pixels per second
do
  local angle = 2*math.pi*love.math.random() -- choose a random direction
  ball.vx = cos(angle) * speed
  ball.vy = sin(angle) * speed
end

-- Do something like this when you need to update
ball.x = ball.x + ball.vx * dt
ball.y = ball.y + ball.vy * dt

-- Do something like this when you detect bouncing on a horizontal wall
ball.vy = -ball.vy

-- Do something like this when you detect bouncing on a vertical wall
ball.vx = -ball.vx
You will typically also need to correct the position of the ball when it bounces, because when you detect the collision, it's already past the wall. That's called collision resolution. If you have trouble with that, maybe you could use a library that handles it.

Yeah I saw your post on how that isn't lerping, I just didn't know what else to call it :P

and thanks, I got the directions working :D also: "You will typically also need to correct the position of the ball when it bounces," don't I just do something like

Code: Select all

if ball.x <= 0 then
	ball.x = 0
	ball.vx = -ball.vx
end
isn't it that or is it more complicated? Because that's what I did and it seems to work.
User avatar
pgimeno
Party member
Posts: 3548
Joined: Sun Oct 18, 2015 2:58 pm

Re: lerping - how to continue past target position

Post by pgimeno »

Vimm wrote:and thanks, I got the directions working :D also: "You will typically also need to correct the position of the ball when it bounces," don't I just do something like

Code: Select all

if ball.x <= 0 then
	ball.x = 0
	ball.vx = -ball.vx
end
isn't it that or is it more complicated? Because that's what I did and it seems to work.
Yes, since in your case the bouncing surface is the border of the screen and the ball doesn't go very fast, that works. For a Pong-type game, for example, things can get more complicated. And if your ball goes faster, setting x = 0 may not give a fully correct visual effect; you may need to set x = -x (for the left border) or x = width-x (for the right border), and similarly for y.
Post Reply

Who is online

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