Difference between revisions of "Math.distance"
From GiderosMobile
(8 intermediate revisions by 2 users not shown) | |||
Line 4: | Line 4: | ||
=== Description === | === Description === | ||
− | Returns the distance | + | Returns the distance betwen two points. |
− | < | + | <syntaxhighlight lang="lua"> |
(number) = math.distance(x1,y1,z1,x2,y2,z2) | (number) = math.distance(x1,y1,z1,x2,y2,z2) | ||
(number) = math.distance({x1,y1,z1},{x2,y2,z2}) | (number) = math.distance({x1,y1,z1},{x2,y2,z2}) | ||
(number) = math.distance({x=x1,y=y1,z=z1},{x=x2,y=y2,z=z2}) | (number) = math.distance({x=x1,y=y1,z=z1},{x=x2,y=y2,z=z2}) | ||
− | </ | + | </syntaxhighlight> |
+ | |||
+ | '''Note''': the number will always be a positive number | ||
=== Parameters === | === Parameters === | ||
Line 20: | Line 22: | ||
=== Return values === | === Return values === | ||
− | '''Returns''' (number) the distance between the two points<br/> | + | '''Returns''' (number) the distance between the two points (always positive)<br/> |
+ | |||
+ | === Example === | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | local mydist = 256 | ||
+ | function LevelX:onEnterFrame(e) | ||
+ | -- player position | ||
+ | posx, posy = self.player1.body:getPosition() | ||
+ | -- for perfs | ||
+ | for k, v in pairs(self.myobjects) do -- k=sprite, v=box2d body | ||
+ | local x1, y1 = v:getPosition() | ||
+ | if math.distance(x1, y1, posx, posy) > mydist then | ||
+ | k:setVisible(false) | ||
+ | else | ||
+ | k:setVisible(true) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === '''Alternatives''' === | ||
+ | The math.distance may not be the fastest. Here are some tests: | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- distance (based on simple functions test timer by @antix) | ||
+ | local distance, random, sqrt = math.distance, math.random, math.sqrt | ||
+ | |||
+ | local x1, y1, x2, y2 = random(-10000, 10000), random(-10000, 10000), random(-10000, 10000), random(-10000, 10000) | ||
+ | |||
+ | -- classic (boring!) | ||
+ | local dx, dy | ||
+ | -- with vectors | ||
+ | local p1, p2 = vector(x1, y1), vector(x2, y2) | ||
+ | |||
+ | -- init | ||
+ | local dist = distance(x1, y1, x2, y2) | ||
+ | print("") | ||
+ | print("*** POINT A: "..x1, y1, "POINT B: "..x2, y2) | ||
+ | print("*** DISTANCE: "..dist) | ||
+ | |||
+ | dist = #(p2-p1) | ||
+ | print("*** VECTORS DIST.: "..dist) | ||
+ | print("") | ||
+ | |||
+ | -- tests | ||
+ | local data = { | ||
+ | { | ||
+ | "sqrt ", | ||
+ | function() | ||
+ | dx, dy = x2-x1, y2-y1 | ||
+ | dist = sqrt(dx*dx + dy*dy) | ||
+ | end, -- 50ms | ||
+ | }, | ||
+ | { | ||
+ | "exponent ", | ||
+ | function() | ||
+ | dx, dy = x2-x1, y2-y1 | ||
+ | dist = (dx^2 + dy^2)^0.5 | ||
+ | end, -- 37ms | ||
+ | }, | ||
+ | { | ||
+ | "multiply/exponent ", | ||
+ | function() | ||
+ | dx, dy = x2-x1, y2-y1 | ||
+ | dist = (dx*dx + dy*dy)^0.5 | ||
+ | end, -- 40ms | ||
+ | }, | ||
+ | { | ||
+ | "multiply/exponent without power", | ||
+ | function() | ||
+ | dx, dy = x2-x1, y2-y1 | ||
+ | -- dist = dx*dx + dy*dy | ||
+ | dist = dx^2 + dy^2 | ||
+ | end, -- 36ms but wrong result! | ||
+ | }, | ||
+ | { | ||
+ | "math.distance ", | ||
+ | function() | ||
+ | dist = distance(x1, y1, x2, y2) | ||
+ | end, -- 53ms | ||
+ | }, | ||
+ | { | ||
+ | "Luau VECTORS ", | ||
+ | function() | ||
+ | dist = #(p2-p1) | ||
+ | end, -- 24ms => this is our WINNER (Gideros 2024.11+) | ||
+ | }, | ||
+ | } | ||
+ | |||
+ | -- run all functions | ||
+ | for i = 1, #data do | ||
+ | local block = data[i] | ||
+ | local func = block[2] | ||
+ | local start = os.timer() | ||
+ | for i = 1, 1000000 do -- 1 million repetitions! | ||
+ | func() | ||
+ | end | ||
+ | local elapsed = math.floor((os.timer() - start) * 1000) | ||
+ | print(block[1].." ("..elapsed.."ms)", "", "distance: "..dist) | ||
+ | end | ||
+ | |||
+ | --[[ RESULTS | ||
+ | |||
+ | *** POINT A: -4709 7129 POINT B: 5172 7263 | ||
+ | *** DISTANCE: 9881.908570716489 | ||
+ | *** VECTORS DIST.: 9881.908520118976 | ||
+ | |||
+ | sqrt (50ms) distance: 9881.908570716489 | ||
+ | exponent (37ms) distance: 9881.908570716489 | ||
+ | multiply/exponent (40ms) distance: 9881.908570716489 | ||
+ | multiply/exponent without power (36ms) distance: 97652117 | ||
+ | math.distance (53ms) distance: 9881.908570716489 | ||
+ | Luau VECTORS (24ms) distance: 9881.908520118976]] | ||
+ | </syntaxhighlight> | ||
{{Math}} | {{Math}} |
Latest revision as of 17:38, 6 November 2024
Available since: Gideros 2020.9
Class: math
Description
Returns the distance betwen two points.
(number) = math.distance(x1,y1,z1,x2,y2,z2)
(number) = math.distance({x1,y1,z1},{x2,y2,z2})
(number) = math.distance({x=x1,y=y1,z=z1},{x=x2,y=y2,z=z2})
Note: the number will always be a positive number
Parameters
x1: (number) X component of the first point
y1: (number) Y component of the first point
z1: (number) Z component of the first point optional
x2: (number) X component of the second point
y2: (number) Y component of the second point
z2: (number) Z component of the second point optional
Return values
Returns (number) the distance between the two points (always positive)
Example
local mydist = 256
function LevelX:onEnterFrame(e)
-- player position
posx, posy = self.player1.body:getPosition()
-- for perfs
for k, v in pairs(self.myobjects) do -- k=sprite, v=box2d body
local x1, y1 = v:getPosition()
if math.distance(x1, y1, posx, posy) > mydist then
k:setVisible(false)
else
k:setVisible(true)
end
end
end
Alternatives
The math.distance may not be the fastest. Here are some tests:
-- distance (based on simple functions test timer by @antix)
local distance, random, sqrt = math.distance, math.random, math.sqrt
local x1, y1, x2, y2 = random(-10000, 10000), random(-10000, 10000), random(-10000, 10000), random(-10000, 10000)
-- classic (boring!)
local dx, dy
-- with vectors
local p1, p2 = vector(x1, y1), vector(x2, y2)
-- init
local dist = distance(x1, y1, x2, y2)
print("")
print("*** POINT A: "..x1, y1, "POINT B: "..x2, y2)
print("*** DISTANCE: "..dist)
dist = #(p2-p1)
print("*** VECTORS DIST.: "..dist)
print("")
-- tests
local data = {
{
"sqrt ",
function()
dx, dy = x2-x1, y2-y1
dist = sqrt(dx*dx + dy*dy)
end, -- 50ms
},
{
"exponent ",
function()
dx, dy = x2-x1, y2-y1
dist = (dx^2 + dy^2)^0.5
end, -- 37ms
},
{
"multiply/exponent ",
function()
dx, dy = x2-x1, y2-y1
dist = (dx*dx + dy*dy)^0.5
end, -- 40ms
},
{
"multiply/exponent without power",
function()
dx, dy = x2-x1, y2-y1
-- dist = dx*dx + dy*dy
dist = dx^2 + dy^2
end, -- 36ms but wrong result!
},
{
"math.distance ",
function()
dist = distance(x1, y1, x2, y2)
end, -- 53ms
},
{
"Luau VECTORS ",
function()
dist = #(p2-p1)
end, -- 24ms => this is our WINNER (Gideros 2024.11+)
},
}
-- run all functions
for i = 1, #data do
local block = data[i]
local func = block[2]
local start = os.timer()
for i = 1, 1000000 do -- 1 million repetitions!
func()
end
local elapsed = math.floor((os.timer() - start) * 1000)
print(block[1].." ("..elapsed.."ms)", "", "distance: "..dist)
end
--[[ RESULTS
*** POINT A: -4709 7129 POINT B: 5172 7263
*** DISTANCE: 9881.908570716489
*** VECTORS DIST.: 9881.908520118976
sqrt (50ms) distance: 9881.908570716489
exponent (37ms) distance: 9881.908570716489
multiply/exponent (40ms) distance: 9881.908570716489
multiply/exponent without power (36ms) distance: 97652117
math.distance (53ms) distance: 9881.908570716489
Luau VECTORS (24ms) distance: 9881.908520118976]]
- Math
- Math.abs
- Math.acos
- Math.asin
- Math.atan
- Math.atan2
- Math.ceil
- Math.clamp
- Math.cos
- Math.cosh
- Math.cross
- Math.deg
- Math.distance
- Math.distances
- Math.dot
- Math.edge
- Math.exp
- Math.fft
- Math.floor
- Math.fmod
- Math.frexp
- Math.ifft
- Math.inside
- Math.ldexp
- Math.length
- Math.log
- Math.log10
- Math.max
- Math.min
- Math.modf
- Math.nearest
- Math.noise
- Math.normalize
- Math.pow
- Math.rad
- Math.random
- Math.randomseed
- Math.raycast
- Math.round
- Math.sign
- Math.sin
- Math.sinh
- Math.sqrt
- Math.tan
- Math.tanh