API talk:1/event details

From Guild Wars 2 Wiki
Jump to navigationJump to search

Deserializing the JSON in its current format is difficult because the event ID becomes the object name/type. I think a more desirable format for future versions of the API would be something like...

{

   "events": [
       {
           "id": "EED8A79F-B374-4AE6-BA6F-B7B98D9D7142",
           "name": "Defeat the renegade charr.",
           "level": 42,
           "map_id": 20,
           "flags": [],
           "location": {
               "type": "sphere",
               "center": [
                   -9463.6,
                   -40310.2,
                   -785.799
               ],
               "radius": 2500,
               "rotation": 0
           }
       },
       {
           "id": "BA2B85C5-DE73-4402-BD84-8F53AA394A52",
           "name": "Bonus Event: Cull the Flame Legion",
           "level": 80,
           "map_id": 929,
           "flags": [
               "group_event"
           ],
           "location": {
               "type": "cylinder",
               "center": [
                   -38.7202,
                   -176.915,
                   -892.494
               ],
               "height": 2027.5,
               "radius": 10314.4,
               "rotation": 0
           }
       },
       {
           "id": "CEA84FBF-2368-467C-92EA-7FA60D527C7B",
           "name": "Find a way to open the door and escape the armory.",
           "level": 8,
           "map_id": 19,
           "flags": [
               "group_event"
           ],
           "location": {
               "type": "poly",
               "center": [
                   -45685.2,
                   -13819.6,
                   -1113
               ],
               "z_range": [
                   -2389,
                   163
               ],
               "points": [
                   [
                       -49395.8,
                       -15845.5
                   ],
                   [
                       -42699.7,
                       -15794.1
                   ],
                   [
                       -43053,
                       -14081.4
                   ],
                   [
                       -43629.7,
                       -11725.4
                   ],
                   [
                       -49647.8,
                       -11651.7
                   ]
               ]
           }
       }
   ]

}

Radius[edit]

To convert the radius of an event from the event coordinate system to the the world coordinate system, the radius can be multiplied by 0.042, or 1/24.

Simple proof:

// From "https://wiki.guildwars2.com/wiki/API:1/event_details#Coordinate_recalculation"
function recalc_coords(continent_rect, map_rect, coords){
	return [
		Math.round(continent_rect[0][0]+(continent_rect[1][0]-continent_rect[0][0])*(coords[0]-map_rect[0][0])/(map_rect[1][0]-map_rect[0][0])),
		Math.round(continent_rect[0][1]+(continent_rect[1][1]-continent_rect[0][1])*(1-(coords[1]-map_rect[0][1])/(map_rect[1][1]-map_rect[0][1])))
	]
}

// From "https://api.guildwars2.com/v1/event_details.json"
var event = {"name":"Defeat the renegade charr.","level":42,"map_id":20,"flags":[],"location":{"type":"sphere","center":[-9463.6,-40310.2,-785.799],"radius":2500,"rotation":0}};

// From "https://api.guildwars2.com/v1/maps.json"
var map = {"map_name":"Blazeridge Steppes","min_level":40,"max_level":50,"default_floor":1,"type":"Public","floors":[0,1,2],"region_id":2,"region_name":"Ascalon","continent_id":1,"continent_name":"Tyria","map_rect":[[-24576,-49152],[24576,49152]],"continent_rect":[[29184,12160],[31232,16256]]};

// Getting what we want
var c = map.continent_rect;
var m = map.map_rect;
var e = event.location.center;
var r = event.location.radius;

// Two sample points
var a = recalc_coords(c, m, e); // First point using event center
var b = recalc_coords(c, m, [e[0],e[1]+r]); // Second point r units vertically displaced from event center, on the outer edge of the circle

console.log(a); // [ 29814, 15888 ]
console.log(b); // [ 29814, 15783 ]

// Difference after converting to world coordinate system
var x = b[1] - a[1];

// Conversion ratio
console.log(x/r); // x = 0.042 .... approximately = 1/24

I wish I knew the reason why it was 1/24. -Chieftain AlexUser Chieftain Alex sig.png 23:50, 27 March 2017 (UTC)

Coordinate recalculation derivation[edit]

We kind of skip over where the equation came from in the article - whilst I think its probably too long to include I thought it'd be of benefit to derive it here.

Preface

The event_details API gives event positions using map coordinates (relative to the zone) instead of the more useful continent coordinates (relative to the entire continent).

The maps API provides both map coordinates and continent coordinates, and therefore provides a way of converting event positions into something that can be plotted on the world map.

Map coordinates

Map coordinates have their origin [0,0] somewhere near the middle of the zone. X increases as you move east. Y increases as you move north.

From the maps API, the map_rect for a zone is specified as the bottom-left and top-right coordinates. For Queensdale this is [[-43008,-27648], [43008,30720]].

Figure 1 - Queensdale plotted with map coordinates. Coordinates increase to the top-right.
Figure 2 - Shadow Behemoth event with distances from the top-left corner marked in Green (mB and mD). Map width and height in Blue (mW and mH). Event position in Orange (mE).

Map width and height are given by:

 mW = map_topright_X - map_bottomleft_X = 86016
 mH = map_topright_Y - map_bottomleft_Y = 58368

mB and mD are given by the distances between the event mE and the topleft corner.

We were not given the topleft corner but we can calculate it.

 map_topleft_X = map_bottomleft_X = -43008
 map_topleft_Y = map_topright_Y  = 30720

From the event_details API we get the Event map position mE = [9835, -17597].

Lengths:

 mB = mEX – map_topleft_X = 9835 - -43008 = 52843
 mD = mEY – map_topleft_Y = -17597 - 30720 = -48317

Ratios:

 mB_ratio = mB / mW = 52843/86016 = 0.6144
 mD_ratio = mD / mH = -48317/58368 = -0.8278
Continent coordinates

Continent coordinates have their origin [0,0] in the North-West. X increases as you move east. Y increases as you move south. (Note that continent Y is inverted with respect to map Y coordinates).

From the maps API, the continent_rect for a zone is specified as the top-left and bottom-right coordinates. For Queensdale this is [[9856,11648], [13440,14080]].

Figure 3 - Tyria with Queensdale plotted with continent coordinates. Coordinates increase to the bottom-right.
Figure 4 - Shadow Behemoth event with distances from the top-left corner of the zone in Green (cB and cD), plus distance from the top-left of the continent to the map in Purple (cA and cC). Continent map width and height in Blue (cW and cH). Event position in Orange (cE).

The continent event position will be given by the combined lengths of the dashed purple (same as the top-left corner of Queensdale) and green lines.

 cEX = cA + cB
 cEY = cC + cD

The lengths of B and D are a ratio of the zone's continent Width and Height. The magnitude of these ratios is similar for continent coordinates and map coordinates.

 cW = continent_bottomright_X - continent_topleft_X = 13440 – 9856 = 3584
 cH = continent_bottomright_Y - continent_topleft_Y = 14080 – 11648 = 2432
 cEX = cA + cB = [continent_topleft_X] + [B_ratio * cW]
 cEY = cC + cD = [continent_topleft_Y] + [D_ratio * cH]

Because the map and continent coordinate systems represent increasing values as south and north respectively, we have to convert map coordinate ratios to continent coordinate ratios by inverting the y axis only.

 cB_ratio = 1 * mB_ratio = 1 * 0.6144 = 0.6144
 cD_ratio = (-1) * mD_ratio = -1 * -0.8278 = 0.8278
 cEX = continent_topleft_X + [cB_ratio * cW] = 9856 + [0.6144 * 3584] = 12058
 cEY = continent_topleft_Y + [cD_ratio * cH] = 11648 + [0.8278 * 2432] = 13661

i.e. event translates from [9835, -17597] to [12058, 13661].

Collating equations
 continent_rect: [[continent_topleft_X, continent_topleft_Y],[continent_bottomright_X, continent_bottomright_Y]]
 cW = continent_bottomright_X - continent_topleft_X
 cH = continent_bottomright_Y - continent_topleft_Y
 
 map_rect: [[map_bottomleft_X, map_bottomleft_Y], [map_topright_X, map_topright_Y]]
 mW = map_topright_X - map_bottomleft_X
 mH = map_topright_Y - map_bottomleft_Y
 
 map_topleft_X = map_bottomleft_X
 map_topleft_Y = map_topright_Y
 
 Event coordinates: mE = [mEX, mEY]
 mB = mEX – map_topleft_X
 mD = mEY – map_topleft_Y
 
 mB_ratio = mB / mW
 mD_ratio = mD / mH
 
 cB_ratio = 1 * mB_ratio
 cD_ratio = (-1) * mD_ratio
 
 cEX = continent_topleft_X + [cB_ratio*cW]
 cEY = continent_topleft_Y + [cD_ratio*cH]

Combined:

 cEX = continent_topleft_X + [(  1  * [( mEX – map_bottomleft_X ) / ( map_topright_X - map_bottomleft_X ) ] ) * ( continent_bottomright_X - continent_topleft_X )]
 cEY = continent_topleft_Y + [((-1) * [( mEY – map_topright_Y   ) / ( map_topright_Y - map_bottomleft_Y ) ] ) * ( continent_bottomright_Y - continent_topleft_Y )]
Switching to javascript array notation
 continent_rect: c = [[continent_topleft_X, continent_topleft_Y],[continent_bottomright_X, continent_bottomright_Y]]
 map_rect: m = [[map_bottomleft_X, map_bottomleft_Y], [map_topright_X, map_topright_Y]]
 event coordinates: e_map = [mEX, mEY]
 Continent event X = c[0][0] + (( 1 * (( e_map[0] - m[0][0] ) / ( m[1][0] - m[0][0] ) ) ) * ( c[1][0] - c[0][0] ))
 Continent event Y = c[0][1] + ((-1 * (( e_map[1] - m[1][1] ) / ( m[1][1] - m[0][1] ) ) ) * ( c[1][1] - c[0][1] ))
                      ^           ^                            ^                                     ^ 
    continent zone topleft     y-axis flip   ratio of event position to map zone width or height  continent zone width
Example
 var c = [[9856,11648],[13440,14080]];
 var m = [[-43008,-27648],[43008,30720]];
 var e_map = [9835,-17597];
 var e_continent = [
   Math.round( c[0][0] + (( 1 * (( e_map[0] - m[0][0] ) / ( m[1][0] - m[0][0] ) ) ) * ( c[1][0] - c[0][0] )) ),
   Math.round( c[0][1] + ((-1 * (( e_map[1] - m[1][1] ) / ( m[1][1] - m[0][1] ) ) ) * ( c[1][1] - c[0][1] )) )
 ];

-Chieftain AlexUser Chieftain Alex sig.png 19:13, 14 December 2019 (UTC)

Edit corrected a sentence or two above. -Chieftain AlexUser Chieftain Alex sig.png 11:37, 18 October 2020 (UTC)