Distance formula to calculate speed between two points - WoWInterface
11-12-11, 08:58 AM   #1
A Molten Giant

Join Date: Dec 2005
Posts: 792
Distance formula to calculate speed between two points

I've spotted the InFlight thread about posting distance results of flights, so I wrote a script that parses the DBC data to extract this information, but I am stuck making this function properly:

Code:
```// get delay between two points on a map and the movement speed modifier
function getDelay(\$from, \$to, \$speed) {
\$time = 0;
if(is_array(\$from) && is_array(\$to)) {
\$m1 = \$from['mapId']; \$x1 = \$from['x']; \$y1 = \$from['y']; \$z1 = \$from['z'];
\$m2 = \$to['mapId'];   \$x2 = \$to['x'];   \$y2 = \$to['y'];   \$z2 = \$to['z'];
\$dx = abs(\$x1 - \$x2); // TODO: are these correctly calculated?
\$dy = abs(\$y1 - \$y2); // TODO: are these correctly calculated?
\$R = 1000; // NYI: mean radius of world (mapId)
\$a = pow(sin(\$dx/2), 2) + cos(\$x1)*cos(\$x2)*pow(sin(\$dy/2), 2);
\$c = 2*atan2(sqrt(\$a), sqrt(1-\$a));
\$d = \$R * \$c;
\$S = 10; // NYI: speed constant that will be modified by \$speed (%)
\$time = \$d/(\$S*\$speed);
}
return \$time;
}```
Basically, I have to calculate the distance between the two points (mapId1,x1,y1,z1) and (mapId2,x2,y2,z2) and I have the speed modifier here (100%, 150%, e.g.) but my speed constant and the radius of the mapId will be a challenge, anyone got any help on this matter?

If I get this to work sure I'll post source and best of all no flight addon will have to calculate on the fly, the time it will take to fly the path! One can in advance of a patch calculate the data from the DBC themselves and produce a LUA database with all the exact timers, cool right?

11-12-11, 01:19 PM   #2
Taryble
A Molten Giant

Join Date: Jan 2009
Posts: 811
That would work, assuming that all flight paths are perfectly straight lines.
__________________
-- Taryble

11-12-11, 01:34 PM   #3
Seerah
Fishing Trainer

Join Date: Oct 2006
Posts: 10,759
The way that InFlight and other timers work is by users recording how long it takes to fly from point A to point B. If a new flight is not in the addon's database, then it just measures how long it takes and stores that for next time.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

11-12-11, 01:39 PM   #4
SDPhantom
A Pyroguard Emberseer

Join Date: Jul 2006
Posts: 1,964
If you have absolute coordinates, you don't need MapID. You're also using a bunch of unneeded trig functions.

PHP Code:
``` function getDistance(\$x1,\$y1,\$z1,\$x2,\$y2,\$z2,\$speed)    return sqrt(pow(\$x1-\$x2,2)+pow(\$y1-\$y2,2)+pow(\$z1-\$z2,2))/\$speed;end  ```
Note: \$speed needs to be in the same units as the coordinates, this means since the absolute coordinates of a map are measured in yards, \$speed needs to match it too. For 100% speed, this would be a value of 7.
__________________
 "All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools." -Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 11-12-11 at 01:46 PM.

11-12-11, 01:40 PM   #5
Seerah
Fishing Trainer

Join Date: Oct 2006
Posts: 10,759
(Don't forget that we do not have access to z-coordinates.)
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

11-12-11, 01:41 PM   #6
A Molten Giant

Join Date: Dec 2005
Posts: 792
Thing is if the path isnt a straight line then you add more nodes and make the game slightly wobble (so it's not instant turns) but knowing the distances and angles between two coordinates would also allow you to figure out this wobble and include it in the time delay calculation, so you can achieve calculating the arrival time trough a path of nodes using their distances between each other.

For now my problem is that the paths have mapId relative coordinates so I have to figure out how big let's say northrend is, then outlands, e.g. Looking at MapDataLib for some info but havent gotten a proper formula, yet.

Anyway, there are advantages to calculating the times liek this, for once you can get all times without having to fly yourself to "time" it.

*Edit*

Saw your post SDPhantom, thanks. Gonna work it in, hehe. Yeah, I'm a bit unclear about the formulas, hence they look messy.

The coordinates in the DBC are raw, but not sure if it maters the size of the map, I guess not as long we dont fly across one map to the other (like to azuremyst but thats another problem to figure later on, hehe).

Last edited by Vlad : 11-12-11 at 01:45 PM.

11-12-11, 01:43 PM   #7
Seerah
Fishing Trainer

Join Date: Oct 2006
Posts: 10,759
I don't understand what you mean by "nodes" and "wobble"?
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

11-12-11, 01:57 PM   #8
SDPhantom
A Pyroguard Emberseer

Join Date: Jul 2006
Posts: 1,964
 Originally Posted by Vladinator Thing is if the path isnt a straight line then you add more nodes and make the game slightly wobble (so it's not instant turns) but knowing the distances and angles between two coordinates would also allow you to figure out this wobble and include it in the time delay calculation, so you can achieve calculating the arrival time trough a path of nodes using their distances between each other. For now my problem is that the paths have mapId relative coordinates so I have to figure out how big let's say northrend is, then outlands, e.g. Looking at MapDataLib for some info but havent gotten a proper formula, yet. Anyway, there are advantages to calculating the times liek this, for once you can get all times without having to fly yourself to "time" it. *Edit* Saw your post SDPhantom, thanks. Gonna work it in, hehe. Yeah, I'm a bit unclear about the formulas, hence they look messy. The coordinates in the DBC are raw, but not sure if it maters the size of the map, I guess not as long we dont fly across one map to the other (like to azuremyst but thats another problem to figure later on, hehe).
Internally, all objects are rendered at coordinates based on each continent. I'm not entirely sure what units such coordinates are based off of. I wouldn't automatically assume that it's still in yards.

 Originally Posted by Seerah I don't understand what you mean by "nodes" and "wobble"?
I'm guessing "node" is each point that makes up the actual flight path and "wobble" is the method of which the game smooths out each turn by imposing a limit to the turning rate. However, the turn rate limit may just be enforced by adding more points in a turn to make it look smooth.
__________________
 "All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools." -Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 11-12-11 at 02:01 PM.

11-12-11, 02:08 PM   #9
A Molten Giant

Join Date: Dec 2005
Posts: 792
It's a bit hard to explain, so I'll show some examples of what I mean;

TaxiNodes.dbc contains the columns:
TaxiId, mapId, x, y, z, name, ...

TaxiPath.dbc contains the columns:
PathId, fromTaxiId, toTaxiId, cost

TaxiPathNode.dbc contains the columns:
PathNodeId, PathId, counter, mapId, x, y, z, ...

Combining these information tables you can combine a start and a destination, for example in TaxiNodes.dbc Stormwind is #2 and Goldshire is #582.

Then you check TaxiPath.dbc if you have a PathId for a path fromTaxiId=2 and toTaxiId=582, if not then that taxi path does not exist.

If you do on the other hand, you look the nodes in the path (the mount follows these node by node) in TaxiPathNode.dbc where you look up all PathNodeId where PathId=TaxiPath.PathId and you get a list where counter goes from 0 up to the last node (SW->GS has 16 nodes along the flight path).

Each flight position has coordinates, they are relative to the map and we know the mapId in case we need to translate coordinates (i.e. flying from one map to the other, e.g. maybe it affects the distance calculations, not sure, maybe not).

Anyway, mathematically you can iterate a path of many nodes and each step you take you compare this with the previous (or next, depending how you program it) and get a distance difference by putting the coordinates in a formula, then if you know how fast you are moving you can calculate the time between each node and sum them all up for the total travel time from start to finish.

The only problem so far is the possibility of a "wobble", like this:

Fig. 1 is how the math would calculate distances, straight lines from one point to the other. Fig. 2 is how it feels in the game, you don't fly and instantly turn once you hit a node, instead the game does some sort of wobble to make the transition smooth between nodes.

TaxiNodes = positions you can land and take off
FlightNodes/(I call them nodes in this post) = the orange dots in between the air, not visible but you go from one to the next like waypoints.

*Edit*

SDPhantom the coordinates are on this form (one random line from both files that contain coordinates):
2,0,-8841.05957031,489.656005859,109.607002258,"Stormwind, Elwynn",0,541,1,0.00998003967106,0.0101744187996,
35,6,0,0,-8852.65039063,496.459991455,111.040000916,0x0,0,0,0,
You have the mapId (0 in this case) and the coordinates, it does look like continent coordinates, yes.

*Edit 2*
Just figured I'd put an example output so far, the time is about right for this specific path, but need to find the speed value, it may be variable or constant if lucky. At the moment the speed was set to 30.33... but need to test with more FP to see if it applies to them or not, I think not because of this wobble I mentioned in the post.
 Flying path #557 for 1020 copper: - #128; Shattrath, Terokkar Forest - #121; Allerian Stronghold, Terokkar Forest - parsing nodes along path... -> #start to #14252 (+0.15 seconds) -> #14252 to #14251 (+0.71 seconds) -> #14251 to #14250 (+1.48 seconds) -> #14250 to #14249 (+2.33 seconds) -> #14249 to #14248 (+2.47 seconds) -> #14248 to #14247 (+3.21 seconds) -> #14247 to #14246 (+5.81 seconds) -> #14246 to #14245 (+13.83 seconds) -> #14245 to #14244 (+7.16 seconds) -> #14244 to #14243 (+4.55 seconds) -> #14243 to #14242 (+4.87 seconds) -> #14242 to #14241 (+6.92 seconds) -> #14241 to #14240 (+4.93 seconds) -> #14240 to #14239 (+5.49 seconds) -> #14239 to #14238 (+5.59 seconds) -> #14238 to #14237 (+3.15 seconds) -> #14237 to #14236 (+1.66 seconds) -> #14236 to #end (+0.06 seconds) => arrived destination after 74.36 seconds!

Last edited by Vlad : 11-12-11 at 02:16 PM.

11-12-11, 02:30 PM   #10
SDPhantom
A Pyroguard Emberseer

Join Date: Jul 2006
Posts: 1,964
 Originally Posted by Vladinator Just figured I'd put an example output so far, the time is about right for this specific path, but need to find the speed value, it may be variable or constant if lucky. At the moment the speed was set to 30.33... but need to test with more FP to see if it applies to them or not, I think not because of this wobble I mentioned in the post.
In my experience, the speed of a flight path does vary and is based on the departing point. This seems to decide on what kind of mount you ride on for the duration of the flight and through which, how fast it goes.

In Azeroth, there are only a handful of such mounts it chooses on, which are faction-based and mostly fly the same speed. I think Outland is the same. Where you really see a difference is in Northrend. For example, one flight path would give you a gyrocopter to ride on which is the slowest among the list, while another would give you a dragon mount, which are the fastest.
__________________
 "All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools." -Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 11-12-11 at 02:37 PM.

11-12-11, 03:51 PM   #11
Talyrius
An Onyxian Warder

Join Date: Oct 2008
Posts: 361
 For example, one flight path would give you a gyrocopter to ride on which is the slowest among the list, while another would give you a dragon mount, which are the fastest.
I find it hard to believe that Blizzard would introduce speed variance on fixed flight paths like you're suggesting.

Have you actually verified this or is this a conclusion based on your observations of how fast it feels? I hear people comment on how some mounts feel slower or faster relative to other mounts all the time, but this isn't actually the case. How fast something feels is an imprecise method of measurement.

11-12-11, 05:08 PM   #12
Dridzt
A Pyroguard Emberseer

Join Date: Nov 2005
Posts: 1,257
Try flying Sholazar Basin, it's absolutely verified.

11-12-11, 06:31 PM   #13
SDPhantom
A Pyroguard Emberseer

Join Date: Jul 2006
Posts: 1,964
 Originally Posted by ForeverTheGM I find it hard to believe that Blizzard would introduce speed variance on fixed flight paths like you're suggesting. Have you actually verified this or is this a conclusion based on your observations of how fast it feels? I hear people comment on how some mounts feel slower or faster relative to other mounts all the time, but this isn't actually the case. How fast something feels is an imprecise method of measurement.
It's gathered from the GetUnitSpeed() API function. I had it running on a version of my personal HUD addon while playing.
__________________
 "All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools." -Anders (Dragon Age: Origins - Awakening)

11-12-11, 08:28 PM   #14
A Molten Giant

Join Date: Dec 2005
Posts: 792
Must be some way to do this from the DBCs considering they define the distances and flight related paths...

*Edit*

Good news, tested it flying between SW, Goldshire and Eastvale and the timers expected are about right, only that in-game there can be up to a second delay when you click and actually start to fly, e.g. or between path transitions (i.e. sw to goldshire then it has to hop you on from goldshire to eastvale, that transition can take enough time to add a couple of seconds to the total timer from start to finish if you fly and jump many different paths).

Going to make a function to iterate trough the various possible paths in-game, that exists of course, then store it in a file and check with the current InFlight.lua data and see how much off I am, hehe. If lucky and it's only some seconds differences then it may be my speed constant that needs changing, or changing depending on the path, there are some flags I am not sure what are on taxinodes so if lucky they hold the answer to the speed problem.

*Edit 2*
These are the times for single flights only (no connections):
http://pastebin.com/PJLHijdG (from, to, copper, time)
I've looked in the inflight data and must say it's scary how similar the times are, only a few weird entries like Sentinel Hill to Stormwind is 25 sec on inflight while around 80 on the calculations. :P
For chained flights one has to think about the start->node1 and nodeN->end times and skip them on paths in between, i.e. if you fly Stormwind -> Duskwood -> Blasted Lands one would have to skip the nodeN->end (landing) time between Stormwind and Duskwood, Duskwood and Blasted Lands you need to skip both launch and landing, and at the end you must skip the launch->node1 while include the nodeN->landing times to get it most accurate as you can.
In the DBC the taxi path names are localized so it's a bit tricky to make it easy to work on many locales, considering the ID in the DBC are not accessible trough game API (I think they should make it tough, hehe).

Anyway, these are my findings so far. I'll release my PHP script for the data management and such soon, it's not a big deal, and it's actually a bit noobish in layout. Made it mainly to extract data from DBCs (actually their CSV files after using another program to convert the DBCs) to begin with.

About making the flightmaps tough, this shouldn't be too hard:
1. We have a list of all from and to paths, so all you have to do is scan this array of data and check "I am at X, when is from=X and store the to value in a table with a index of X" thus you end up with for example: {[2]={5,6,8}} where at node 2 you have access to nodes 5, 6 and 8. Then you can do a debt query and go further down, check where does 5 go to, where do 6 go to, e.g. When at the FP in-game you know where you start and you know where you want to go, and the game marks the path so you know the nodes in between, so with something smart you can recursively find these path names and by having some sort of library to convert the names into ID's for example, you can extract the times from the database above and sum up the different times.
I realize you loose the launch->node1 and nodeN->landing times but assume 1+-2 seconds differences in the mathematical from the actual version.
Besides, latency also plays a role, if you have 500ms you will notice slight alteration in the times anyway, you can't get the times 100% accurate, only estimates so it's not a bad idea to use the raw data to generate the flight times I think.

Sorry for blocks of text.

Is there any point me writing this btw? I got the impression someone else is benefiting from this information, maybe not, maybe it's just me...

Last edited by Vlad : 11-13-11 at 08:50 AM.

11-13-11, 04:42 PM   #15
Torhal
A Pyroguard Emberseer

Join Date: Aug 2008
Posts: 1,196
The flightpath speeds are constant per flightpath: The Sholazar flightpath is substantially slower than others.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.

11-13-11, 09:04 PM   #16
A Molten Giant

Join Date: Dec 2005
Posts: 792
Each taxi location has a creature ID (some are 0, not sure what that means really...) anyway these are the current creature ID's:
http://pastebin.com/DHyu3BZY

Somehow one has to extract the information about their speeds from the server, because the DBC do not contain this information.

For example: http://db.mmo-champion.com/c/54271/

11-14-11, 05:02 AM   #17
SDPhantom
A Pyroguard Emberseer

Join Date: Jul 2006
Posts: 1,964
 Originally Posted by Torhal The flightpath speeds are constant per flightpath: The Sholazar flightpath is substantially slower than others.
To avoid confusion and restate what I said earlier with the same clarity... Flight path speeds are determined from the original departure point. This means even when chaining paths to reach your destination, your speed remains constant between hops. Your mount/speed never changes from start to finish. This also means it is entirely possible, between two direct points, to fly faster in one direction than the other.
__________________
 "All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools." -Anders (Dragon Age: Origins - Awakening)

11-14-11, 09:09 AM   #18
Torhal
A Pyroguard Emberseer

Join Date: Aug 2008
Posts: 1,196
That's what I was trying to express, but I was a bit terse about it so I failed miserably.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.

11-14-11, 03:46 PM   #19
A Molten Giant

Join Date: Dec 2005
Posts: 792
If lucky the speeds can be read from the creature when flying... but considering when you mount you can't directly query the creature itself, this will be a bit hard, or maybe it's just a creature ID for the visuals, the speeds may be hardcoded in the exe maybe, since it's a bit unlikely that they are in the DBC, but maybe you are more awesome then me, so I put the files in a zip if you like to peak at the source data.
Attached Files
 Taxi.zip (878.7 KB, 455 views)

11-14-11, 08:17 PM   #20
SDPhantom
A Pyroguard Emberseer

Join Date: Jul 2006
Posts: 1,964
It's readable with a call to GetUnitSpeed("player") while on a taxi.
__________________