Move an object from a point A to a point B

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Nada3
Prole
Posts: 8
Joined: Fri Dec 23, 2016 10:52 am

Move an object from a point A to a point B

Post by Nada3 »

Hello everyone !
I have a new problem and I don't know how to solve it :/
I want to move an object (an image) from a position to a second position (mouse cursor) when I click. But I don't know how to do.
I've searched a math solution but I don't find something interesting.
Hope you can help me !
Thanks :).
User avatar
zorg
Party member
Posts: 3449
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Move an object from a point A to a point B

Post by zorg »

By move, do you mean that you want it to instantly appear there, or to go there with the same speed regardless of distance (constant speed), or to go there under the same amount of time regardless of distance (constant time) or do you want it to speed up first and/or slow down at the end?

All these have somewhat different solutions. :3
Last edited by zorg on Wed Dec 28, 2016 11:54 pm, edited 2 times in total.
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
Nada3
Prole
Posts: 8
Joined: Fri Dec 23, 2016 10:52 am

Re: Move an object from a point A to a point B

Post by Nada3 »

By move, I mean go there with a constant speed.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Move an object from a point A to a point B

Post by raidho36 »

Record your target coordinates somewhere when you click. Also record original coordinates. Then simply produce object coordinates using linear interpolation from origin to target. Alternatively, compute angle to the target and add sine of it to x coordinate and negative cosine of it to y coordinate. Multiply output of the trig functions to increase speed.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Move an object from a point A to a point B

Post by Jasoco »

Look into automating it with a library like Flux.
User avatar
pgimeno
Party member
Posts: 3588
Joined: Sun Oct 18, 2015 2:58 pm

Re: Move an object from a point A to a point B

Post by pgimeno »

For constant speed, a tweening library is not the best approach. To use it you'd need to calculate the travel time in order to adjust the speed to make it constant.

The most straightforward approach (from my point of view, anyway) is to normalize the vector between the current position and the destination position, using either a vector math library or the formula directly; multiply that vector with the required speed times dt, and add it to the object's position, stopping before it overshoots (detecting overshoot is a separate problem; it can be done by detecting total distance travelled and comparing it against the original distance).
User avatar
zorg
Party member
Posts: 3449
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Move an object from a point A to a point B

Post by zorg »

Code: Select all

-- nice to have locals, put them outside any function
local speed, dx, dy, o_x, o_y

function love.load(arrrrgs)
  speed = 1.0 -- seconds -- not speed, time though
  dx,dy -- how much do we need to add/subtract from the below coordinates to get to our goal position with the above speed.
  o_x, o_y = 0,0 -- object coords
end

function love.mousereleased(butt,x,y)
  -- separating axis theorem provides us blah blah blah, doing this works out just as well as converting to a polar coord sys, doing the math there, then converting back (since we need the delta amounts separated anyway)... unless i'm wrong, of course :3
  dx = (o_x - x) / speed
  dy = (o_y - y) / speed
end

function love.update(dt)
  o_x = o_x + dx * dt
  o_y = o_y + dy * dt
end
Again, i might be wrong to say this works, but from a cursory glance, it should; didn't test it.

Though, if it -does- work, it only takes 2-2 subs and divs once per mouse button release, and 2-2 adds and muls once per frame. Contrasting it with conversion between cartesian and polar coordinate systems to and back, those would add squaring, square root, sin, cos function calls; even if it'd only do them once per mouse button release, this is arguably still faster.

Edit: This would actually be the constant time version, whoops...
Last edited by zorg on Thu Dec 29, 2016 11:41 am, edited 1 time in total.
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: 3588
Joined: Sun Oct 18, 2015 2:58 pm

Re: Move an object from a point A to a point B

Post by pgimeno »

Well, it would work (when fixed), but it would not be constant speed.

The reason I suggested to normalize the velocity is to make the speed constant at any angle. What raidho said also works (taking the angle and then the cosine and sine, except he got them reversed), though that method of normalizing uses three costly operations (atan2, cos, sin) vs. one with the other method (sqrt), and is less precise for normalizing a vector than the sqrt method. Which is why normalizing the usual way seems natural.

(For those unfamiliar with the term "normalize": it consists of obtaining a vector with the same direction but length 1; usually calculated by dividing its components by its length, which is in turn calculated using Pythagoras. Once you have it, you can multiply it by the desired length to obtain a vector of that length, in this case the desired speed).

Here's my proposed method, including accurate arrival:

Code: Select all

local speed = 100 -- desired speed in pixels/s

local obj_x, obj_y = 400, 300
local obj_vx, obj_vy = 0, 0

local pos_at_click_x, pos_at_click_y = obj_x, obj_y
local target_x, target_y = obj_x, obj_y
local dist_at_click2 = 0

function love.mousepressed(x, y, b)
  pos_at_click_x = obj_x
  pos_at_click_y = obj_y
  target_x = x
  target_y = y
  -- Calculate and remember the square of the distance to travel
  dist_at_click2 = (target_x - obj_x)^2 + (target_y - obj_y)^2

  -- Divide displacement vector by its length to normalize it,
  -- and multiply resulting unit vector by speed
  if dist_at_click2 == 0 then
    obj_vx, obj_vy = 0, 0 -- avoid division by 0
  else
    local dist_at_click = math.sqrt(dist_at_click2)
    obj_vx = (target_x - obj_x) / dist_at_click * speed
    obj_vy = (target_y - obj_y) / dist_at_click * speed
  end
end

function love.update(dt)
  obj_x = obj_x + obj_vx * dt
  obj_y = obj_y + obj_vy * dt

  -- Check if overshooting (we check the square of the distance to avoid
  -- calculating a square root)
  local dist = (pos_at_click_x - obj_x)^2 + (pos_at_click_y - obj_y)^2
  if dist >= dist_at_click2 then
    -- Overshot - teleport to target instead.
    obj_x = target_x
    obj_y = target_y
    obj_vx = 0
    obj_vy = 0
  end
end

function love.draw()
  love.graphics.rectangle("line", obj_x-0.5, obj_y-0.5, 3, 3)
end
User avatar
Nada3
Prole
Posts: 8
Joined: Fri Dec 23, 2016 10:52 am

Re: Move an object from a point A to a point B

Post by Nada3 »

Thank's a lot for you answers !
I will use the code pgimeno I thin :-).
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests