Page 1 of 1

mental and code gymnastics

Posted: Fri Dec 09, 2022 12:21 am
by togFox
I have a function I've used for a long time - it measures the distance between two points using Euclidean technique. It is a well documented and easily googleable formula (I know this can be done in one line but I wrote this a long time ago to assist my learning):

Code: Select all

function getDistance(x1, y1, x2, y2)
	-- this is real distance in pixels or some other unit
	-- receives two coordinate pairs (not vectors)
	-- returns a single number without any rounding
	-- Euclidean distance

	if (x1 == nil) or (y1 == nil) or (x2 == nil) or (y2 == nil) then return 0 end

        local horizontal_distance = x1 - x2
        local vertical_distance = y1 - y2
        -- both of these next two lines work the same
        local a = horizontal_distance * horizontal_distance
        local b = vertical_distance ^2

        local c = a + b
        local distance = math.sqrt(c)
        return distance
end
This of course manages two points (four parameters). My Lua foo fails me sometimes and now is one of those times. How do I adjust my function so it can handle three pairs (3d space) or four pairs or, actually - I need it to handle N pairs.

I think I'm getting stuck on receiving an unknown number of parameters, understanding how many were actually received, and then calculating the distance between those unknown pairs. Just to be clear - I understand how to calculate the distance between 3, 4 or 5 pairs - I just don't know how many pairs there will be!

___________________________
AB=√(x2−x1)^2+(y2−y1)^2+(z2−z1)^2

So, restating the problem - how to adjust the function so it can receive n co-ordinates in space that has n axis?

Re: mental and code gymnastics

Posted: Fri Dec 09, 2022 7:13 am
by knorke
In Lua a function can have a variable amount of parameters:
http://www.wellho.net/resources/ex.php?item=u106/vargs
(random google hit)

So maybe like this:

Code: Select all

function getDistance( ... )
if #args==4 then
--calculate 2d distance with first point at args[1],args[2]
--second point at args[3], args[4]
end

if #args==6 then
--calculate 3d distance with first point at args[1], args[2], args[3]
--second point at args[4], args[5], args[6]
end
end
(Instead of the if's you could do something more clever to handle coordinate systems with n axes, for example the first n/2 args define point1 and the second n/2 args define point2)

Another way is to pass each point as a table.

Re: mental and code gymnastics

Posted: Fri Dec 09, 2022 8:00 am
by darkfrei
Letters x,y,z etc. are nice, but why not numbers?
Let one point be a = {1, 2, 3} and the other point b = {4, 5} (here no third coordinate means that the third coordinate is 0).
So,

Code: Select all

function getDistance (a, b) -- distance between points a and b
	local len = math.max (#a, #b) -- get the highest space dimension
	local sum = 0
	for i = 1, len do
		local ai = a[i] or 0
		local bi = b[i] or 0
		sum = sum + (bi-ai)^2
	end
	return math.sqrt(sum)
end

Re: mental and code gymnastics

Posted: Fri Dec 09, 2022 3:19 pm
by pgimeno
arg (not args) doesn't work in LuaJIT. What you're looking for is select().

Code: Select all

local function n_dimensional_dist(...)
  local nargs = select('#', ...)
  local half = nargs * 0.5
  local sum = 0
  for i = 1, half do
    local component1 = select(i, ...)
    local component2 = select(i + half, ...)
    sum = sum + (component2 - component1)^2
  end
  return math.sqrt(sum)
end
(Caveat: untested)

(Caveat 2: select() is NYI)

Re: mental and code gymnastics

Posted: Fri Dec 09, 2022 3:43 pm
by zorg
pgimeno wrote: Fri Dec 09, 2022 3:19 pm (Caveat 2: select() is NYI)
Sadly that link no longer works; although there was a caveat with that too; some select statements were not NYI, i believe constant indice ones... i just don't remember whether # was also included or not.

Re: mental and code gymnastics

Posted: Fri Dec 09, 2022 8:18 pm
by pgimeno
Right, thanks. Here's an Internet Archive link: http://web.archive.org/web/202207171208 ... it.org/NYI