Page 1 of 1
Move an object from a point A to a point B
Posted: Wed Dec 28, 2016 7:13 pm
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
.
Re: Move an object from a point A to a point B
Posted: Wed Dec 28, 2016 7:25 pm
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.
Re: Move an object from a point A to a point B
Posted: Wed Dec 28, 2016 7:54 pm
by Nada3
By move, I mean go there with a constant speed.
Re: Move an object from a point A to a point B
Posted: Wed Dec 28, 2016 8:37 pm
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.
Re: Move an object from a point A to a point B
Posted: Wed Dec 28, 2016 8:48 pm
by Jasoco
Look into automating it with a library like Flux.
Re: Move an object from a point A to a point B
Posted: Wed Dec 28, 2016 10:55 pm
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).
Re: Move an object from a point A to a point B
Posted: Thu Dec 29, 2016 12:02 am
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...
Re: Move an object from a point A to a point B
Posted: Thu Dec 29, 2016 1:29 am
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
Re: Move an object from a point A to a point B
Posted: Thu Dec 29, 2016 10:41 am
by Nada3
Thank's a lot for you answers !
I will use the code pgimeno I thin :-).