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 .
Move an object from a point A to a point B
- zorg
- Party member
- Posts: 3470
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Move an object from a point A to a point B
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.
All these have somewhat different solutions.
Last edited by zorg on Wed Dec 28, 2016 11:54 pm, edited 2 times in total.
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.
Re: Move an object from a point A to a point B
By move, I mean go there with a constant speed.
Re: Move an object from a point A to a point B
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.
- Jasoco
- Inner party member
- Posts: 3727
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Move an object from a point A to a point B
Look into automating it with a library like Flux.
Re: Move an object from a point A to a point B
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).
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).
- zorg
- Party member
- Posts: 3470
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Move an object from a point A to a point B
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
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 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.
Re: Move an object from a point A to a point B
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:
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
Thank's a lot for you answers !
I will use the code pgimeno I thin :-).
I will use the code pgimeno I thin :-).
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 2 guests