This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
jewelshisen's profile picture

3D distance formula in CC

Started by jewelshisen, 20 January 2013 - 03:21 PM
jewelshisen #1
Posted 20 January 2013 - 04:21 PM
Hello! I am currently trying to make a program that will use the radar from the ICBM mod to track an incoming missile and then activate an MFFS force field if it comes too close to my base. To that end I need to know how you program in the square root function. I have the base of my code made and any tips on how to fetch the x,y,z variables out of the table that the radar puts out would be greatly appreciated. Here is my code so far:


radar=peripheral.wrap("back:red")

function ping()
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
    print(v)
  end
end

while true do
  ping()
  sleep(0.1)
end

RunasSudo-AWOLindefinitely #2
Posted 20 January 2013 - 04:22 PM
http://en.wikipedia....lidean_distance
Try the Euclidean distance formula.

dist = math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2) + math.pow(z1 - z2, 2))
I think

As for getting the locations, I believe you can use v[1], v[2] and v[3].
I believe v[1] = x, v[2] = z and v[3] = y, but I don't have the mod, so I cannot confirm this.
Edited on 20 January 2013 - 03:27 PM
jewelshisen #3
Posted 20 January 2013 - 04:25 PM
http://en.wikipedia....lidean_distance
Try the Euclidean distance formula.

dist = math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2) + math.pow(z1 - z2, 2))
I think

I said I know the formula… I just needed the lua script. But thanks.
theoriginalbit #4
Posted 20 January 2013 - 04:27 PM
http://en.wikipedia....lidean_distance
Try the Euclidean distance formula.

dist = math.sqrt(math.pow(x1 - x2, 2) + math.pow(y1 - y2, 2) + math.pow(z1 - z2, 2))
I think
yeh that looks about right…
jewelshisen #5
Posted 20 January 2013 - 04:29 PM
Thanks. Now to figure out how to get the missile variables out of the table.
RunasSudo-AWOLindefinitely #6
Posted 20 January 2013 - 04:30 PM
Thanks. Now to figure out how to get the missile variables out of the table.
I updated my answer with information
theoriginalbit #7
Posted 20 January 2013 - 04:31 PM
Loop the entities with a numeric for loop then to this…

radarEntities[i]["x"]
radarEntities[i]["y"]
radarEntities[i]["z"]
jewelshisen #8
Posted 20 January 2013 - 04:33 PM
Loop the entities with a numeric for loop then to this…

radarEntities[i]["x"]
radarEntities[i]["y"]
radarEntities[i]["z"]

Well I am already using the for loop to display the missile location so couldn't I just use a modification of that?
RunasSudo-AWOLindefinitely #9
Posted 20 January 2013 - 04:35 PM

local entities = {}
function ping()
  term.clear()
  term.setCursorPos(1,1)
  entities = {}
  for i,v in pairs(radar.getEntities()) do
	entities[#entities + 1]["x"] = v[1]
	entities[#entities + 1]["z"] = v[2]
	entities[#entities + 1]["y"] = v[3]
  end
end

EDIT: Woo! Level up!
jewelshisen #10
Posted 20 January 2013 - 04:41 PM

local entities = {}
function ping()
  term.clear()
  term.setCursorPos(1,1)
  entities = {}
  for i,v in pairs(radar.getEntities()) do
	entities[#entities + 1]["x"] = v[1]
	entities[#entities + 1]["z"] = v[2]
	entities[#entities + 1]["y"] = v[3]
  end
end

EDIT: Woo! Level up!

I'm not trying to make a new table… I'm trying to get info OUT of the table and IN to variables. The getEntities method RETURNS a table that does me no good for plugging into a math formula.
Lyqyd #11
Posted 20 January 2013 - 04:44 PM
You're going to want it in tables anyhow, if you want to be able to track more than just one missile at a time. What's the opposition to tables?
RunasSudo-AWOLindefinitely #12
Posted 20 January 2013 - 04:44 PM
I'm not trying to make a new table… I'm trying to get info OUT of the table and IN to variables. The getEntities method RETURNS a table that does me no good for plugging into a math formula.
*sigh*. Do you want me to spell it out for you? Alright…

function ping()
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
        local x = v[1]
        local z = v[2]
        local y = v[3]
  end
end
Plug values into distance formula.
Edited on 20 January 2013 - 03:45 PM
jewelshisen #13
Posted 20 January 2013 - 04:45 PM
You're going to want it in tables anyhow, if you want to be able to track more than just one missile at a time. What's the opposition to tables?

Because the ICBM radar doesn't return the location for more than one missile.
jewelshisen #14
Posted 20 January 2013 - 04:48 PM
I'm not trying to make a new table… I'm trying to get info OUT of the table and IN to variables. The getEntities method RETURNS a table that does me no good for plugging into a math formula.
*sigh*. Do you want me to spell it out for you? Alright…

function ping()
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
		local x = v[1]
		local z = v[2]
		local y = v[3]
  end
end
Plug values into distance formula.

I'm not trying to be difficult but I have never used tables and never taken any kind of programming class, be it college or CC University. I'm learning this as I go along.
RunasSudo-AWOLindefinitely #15
Posted 20 January 2013 - 04:48 PM
Because the ICBM radar doesn't return the location for more than one missile.
I'm.. sorry? Forgive me if there is a simple explanation, but why is there a radar.getEntities function if it only returns data for one missile? Seems a bit of an odd implementation?

I'm not trying to be difficult but I have never used tables and never taken any kind of programming class, be it college or CC University. I'm learning this as I go along.
Alright then. We all had to learn something at some point.
Edited on 20 January 2013 - 03:49 PM
jewelshisen #16
Posted 20 January 2013 - 04:52 PM
Because the ICBM radar doesn't return the location for more than one missile.
I'm.. sorry? Forgive me if there is a simple explanation, but why is there a radar.getEntities function if it only returns data for one missile? Seems a bit of an odd implementation?

Don't look at me… The GUI for the radar will show more than one missile so I *assume* there is a way to track more than one missile but I have no clue how.

I'm not trying to be difficult but I have never used tables and never taken any kind of programming class, be it college or CC University. I'm learning this as I go along.
Alright then. We all had to learn something at some point.

I know and I am thankful for the help. I just tend to get frustrated easily when I don't understand things.
theoriginalbit #17
Posted 20 January 2013 - 04:56 PM
The getEntities function AND the getBlocks function BOTH return the data in a table…




function ping()
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
	local entityX = v["x"]
	local entityY = v["y"]
	local entityZ = v["z"]
	print( "Distance: "..-- formula goes here )
  end
end
Edited on 20 January 2013 - 03:58 PM
jewelshisen #18
Posted 20 January 2013 - 05:17 PM
Ok I have hit an issue… Here is my code:


radar=peripheral.wrap("back:red")
print("Enter X:")
x1=tonumber(read())
print("Enter Y:")
y1=tonumber(read())
print("Enter Z:")
z1=tonumber(read())
function ping(x1,y1,z1)
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
    print(v)
    local entityX=v[1]
    local entityY=v[2]
    local entityZ=v[3]
    dist=math.sqrt(math.pow(x1-entityX,2)+math.pow(y1-entityY,2)+math.pow(z1-entityZ,2))
    print("Distance: "..dist)
  end
end

while true do
  ping()
  sleep(0.1)
end


The problem I have is that at like 13 it tells me 'attempt to index ? <a number value> '

What did I do wrong?
theoriginalbit #19
Posted 20 January 2013 - 05:19 PM
Ok I have hit an issue… Here is my code:


radar=peripheral.wrap("back:red")
print("Enter X:")
x1=tonumber(read())
print("Enter Y:")
y1=tonumber(read())
print("Enter Z:")
z1=tonumber(read())
function ping(x1,y1,z1)
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
	print(v)
	local entityX=v[1]
	local entityY=v[2]
	local entityZ=v[3]
	dist=math.sqrt(math.pow(x1-entityX,2)+math.pow(y1-entityY,2)+math.pow(z1-entityZ,2))
	print("Distance: "..dist)
  end
end

while true do
  ping()
  sleep(0.1)
end


The problem I have is that at like 13 it tells me 'attempt to index ? <a number value> '

What did I do wrong?
Thats because the x,y,z data isn't stored in index 1 2 and 3… its stored in as a key/value!!!! Read my reply… I don't make it a habit to repeating myself for a 3rd time!
jewelshisen #20
Posted 20 January 2013 - 05:24 PM
Thats because the x,y,z data isn't stored in index 1 2 and 3… its stored in as a key/value!!!! Read my reply… I don't make it a habit to repeating myself for a 3rd time!

Sorry. Missed the quote marks.
theoriginalbit #21
Posted 20 January 2013 - 05:25 PM
Thats because the x,y,z data isn't stored in index 1 2 and 3… its stored in as a key/value!!!! Read my reply… I don't make it a habit to repeating myself for a 3rd time!
Sorry. Missed the quote marks.
not just quote marks… you had numbers instead of "x" "y" "z"
jewelshisen #22
Posted 20 January 2013 - 05:29 PM
Thats because the x,y,z data isn't stored in index 1 2 and 3… its stored in as a key/value!!!! Read my reply… I don't make it a habit to repeating myself for a 3rd time!
Sorry. Missed the quote marks.
not just quote marks… you had numbers instead of "x" "y" "z"

Yea. Sorry i missed that. >_<
jewelshisen #23
Posted 20 January 2013 - 05:34 PM
Ok… This makes no sense… I have tried it with the x,y,z and i still get the same error…


radar=peripheral.wrap("back:red")
print("Enter X:")
x1=tonumber(read())
print("Enter Y:")
y1=tonumber(read())
print("Enter Z:")
z1=tonumber(read())
function ping(x1,y1,z1)
  term.clear()
  term.setCursorPos(1,1)
  for i,v in pairs(radar.getEntities()) do
    local entityY=v["y"]
    local entityX=v["x"]
    local entityZ=v["z"]
    dist=math.sqrt(math.pow(x1-entityX,2)+math.pow(y1-entityY,2)+math.pow(z1-entityZ,2))
    print("Distance: "..dist)
  end
end

while true do
  ping()
  sleep(0.1)
end

RunasSudo-AWOLindefinitely #24
Posted 20 January 2013 - 05:58 PM
Try doing a

for i2,v2 in pairs(v) do
  print(i2 .. "=" .. v2)
end
instead of getting the x/y/z and calculating the distance, just to see what sort of data is in the table.
jewelshisen #25
Posted 20 January 2013 - 06:03 PM
Try doing a

for i2,v2 in pairs(v) do
  print(i2 .. "=" .. v2)
end
instead of getting the x/y/z and calculating the distance, just to see what sort of data is in the table.
I did this:

for i,v in pairs(radar.getEntities()) do
  print(i..","..v)
end

It returns something like:
y,240
x,70
z,-240
RunasSudo-AWOLindefinitely #26
Posted 20 January 2013 - 06:06 PM
-snip-
Odd. Can you try something like

print(i)
before doing the i2,v2 thing?

  for i,v in pairs(radar.getEntities()) do
    print(i) --This
    for i2,v2 in pairs(v) do
      print(i2 .. "=" .. v2)
    end
  end
Edited on 20 January 2013 - 05:06 PM
jewelshisen #27
Posted 20 January 2013 - 06:10 PM
I just returns y x z on three different lines.
ChunLing #28
Posted 20 January 2013 - 06:24 PM
Yes…I'm not sure what RunasSudo was thinking there (apparently that the values were subtables, though why I can't imagine, perhaps because your posted code makes the same error?).

Perhaps you should change the function to look more like:
function ping(x1,y1,z1)
	term.clear()
	term.setCursorPos(1,1)
    local p = radar.getEntities()
    local dist=math.sqrt(math.pow(x1-p.x,2)+math.pow(y1-p.y,2)+math.pow(z1-p.z,2))
	print("Distance: "..dist)
end
I don't know if this will work exactly, as I don't have the ICBM mod.

Also, this code is a bit sloppy, I just hastily edited what you had. I did I f it does work you'll want to clean it some.
Edited on 20 January 2013 - 05:35 PM
jewelshisen #29
Posted 20 January 2013 - 06:27 PM
Yes…I'm not sure what RunasSudo was thinking there (apparently that the values were subtables, though why I can't imagine, perhaps because your posted code makes the same error?).

Perhaps you should change the function to look more like:
function ping(x1,y1,z1)
    term.clear()
    term.setCursorPos(1,1)
    v = radar.getEntities()
    dist=math.sqrt(math.pow(v.x,2)+math.pow(y1-v.y,2)+math.pow(z1-v.z,2))
    print("Distance: "..dist)
end
I don't know if this will work exactly, as I don't have the ICBM mod.

Well i know that the getEntities() function returns a table but i will try your suggestion.
ChunLing #30
Posted 20 January 2013 - 06:33 PM
Yes, and you can access string indexed values of a table by writing the table name and the string index separated by a ".", as in "v.x". This only works for string indexes, but since that's what we're dealing with I didn't think it would be a problem.

Really, both v and dist should be declared local, and I noticed that I accidentally deleted the x1- from your formula, so the answer will be wrong :o/>

Very sloppy of me. Let me get those.
jewelshisen #31
Posted 20 January 2013 - 06:37 PM
Yes, and you can access string indexed values of a table by writing the table name and the string index separated by a ".", as in "v.x". This only works for string indexes, but since that's what we're dealing with I didn't think it would be a problem.

Really, both v and dist should be declared local, and I noticed that I accidentally deleted the x1- from your formula, so the answer will be wrong :o/>/>/>

Very sloppy of me. Let me get those.

Any way to make it wait for the getEntities() to not return nil so it stops giving an error?

Edit: Also How can i give it zero values for the v.x and so on as holder values so it won't error out?
RunasSudo-AWOLindefinitely #32
Posted 20 January 2013 - 07:32 PM
Yes…I'm not sure what RunasSudo was thinking there (apparently that the values were subtables, though why I can't imagine, perhaps because your posted code makes the same error?).
I was sort of wondering what the keys for the getEntities table were (whether they were 'normal' like 1,2,3 or something weird like 'pig', 'cow170', 'OMGITSACREEPPPPEERRRR'). Not sure why you thought I thought the values were subtables…

Any way to make it wait for the getEntities() to not return nil so it stops giving an error?

Edit: Also How can i give it zero values for the v.x and so on as holder values so it won't error out?

local entities = radar.getEntities()
if entities then   --This checks to see if entities is not nil
  --Do loopy thing
  local x = v.x
  local y = v.y
  local z = v.z
  if x and y and z then   --This checks to see if all are not nil
    --Calculate distance
  end
end
theoriginalbit #33
Posted 20 January 2013 - 07:52 PM
Edit: Also How can i give it zero values for the v.x and so on as holder values so it won't error out?


local x = v.x or 0
local y = v.y or 0
local z = v.z or 0
If any of them are nil they will be set to 0…
jewelshisen #34
Posted 20 January 2013 - 08:37 PM
Edit: Also How can i give it zero values for the v.x and so on as holder values so it won't error out?


local x = v.x or 0
local y = v.y or 0
local z = v.z or 0
If any of them are nil they will be set to 0…

And finially my program is done!!!