Well, with target.x, target.y denoting the target position (i.e. mouse) and pos.x, pos.y denoting the objects position, your code boils down to:
Code: Select all
local angle = math.atan2(target.y - pos.y, target.x - pos.x)
local dx = math.cos(angle) * speed
local dy = math.sin(angle) * speed
That's two subtractions and two multiplications, which are done in practically no time, but
three calls to relatively expensive trigonometric functions, math.atan, math.cos and math.sin.
Ivans method is based on vectors:
Code: Select all
local dx = target.x - pos.x
local dy = target.y - pos.y
local len = math.sqrt(dx*dx + dy*dy)
dx = dx/len * speed -- can be packed into len
dy = dy/len * speed
I.e. one sum, two subtractions, four multiplications, and two divisions (all of which are pretty fast) and only one more expensive call to math.sqrt.
Benchmarking both approaches against each other:
Code: Select all
function trig(target, pos, speed)
local angle = math.atan2(target.y - pos.y, target.x - pos.x)
local dx = math.cos(angle) * speed
local dy = math.sin(angle) * speed
return dx,dy
end
function vectors(target, pos, speed)
local dx = target.x - pos.x
local dy = target.y - pos.y
local len = math.sqrt(dx*dx + dy*dy)
dx = dx/len * speed
dy = dy/len * speed
return dx,dy
end
function nothing() end
function profile(func, iterations)
math.randomseed(1) -- to get the same numbers
local start = os.clock()
for i=1,iterations do
local target = {x = (math.random()*2 - 1) * 100, y = (math.random()*2 - 1) * 100}
local pos = {x = (math.random()*2 - 1) * 100, y = (math.random()*2 - 1) * 100}
func(target, pos, math.random() * 10 + 5)
end
return os.clock() - start
end
Yields (results may vary):
Code: Select all
> print("time:", profile(nothing, 1000000) )
time: 3.14
> print("time:", profile(trig, 1000000) )
time: 4.78
> print("time:", profile(vectors, 1000000) )
time: 3.97
> print("relative time:", (profile(vectors, 1000000) - profile(nothing, 1000000)) / (profile(trig, 1000000) - profile(nothing, 1000000)) )
relative time: 0.49056603773585
So you can see that excluding the boilerplate code, the vector approach is about 50% faster than the trigonometry one.
In the end it probably doesn't matter, but I for one prefer to work with vectors. Interestingly both methods are equivalent (see
here).
Edit: code correction (atan2)