Difference between revisions of "Math.distance"

From GiderosMobile
(positive)
 
(5 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
=== Description ===
 
=== Description ===
 
Returns the distance betwen two points.
 
Returns the distance betwen two points.
<source lang="lua">
+
<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})
</source>
+
</syntaxhighlight>
  
 
'''Note''': the number will always be a positive number
 
'''Note''': the number will always be a positive number
Line 25: Line 25:
  
 
=== Example ===
 
=== Example ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
local mydist = 256
 
local mydist = 256
 
function LevelX:onEnterFrame(e)
 
function LevelX:onEnterFrame(e)
Line 40: Line 40:
 
end
 
end
 
end
 
end
</source>
+
</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]]