Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/guides/map-data/cluster_map_2d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 17 additions & 5 deletions docs/guides/map-data/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Objects like regions, constellations, solarsystems, planets, moons, and other ce
There are two kinds of position, each using their own coordinate system:

* Relative to the center of the New Eden cluster. (Used by regions, constellations, solarsystems)<br>
The center of the cluster lies near Zarzakh, labelled "Point of No Return" on the in-game map. (See the red dot on the cluster map below)
The center of the cluster lies near Zarzakh, labelled "Point of No Return" on the in-game map. (See the red dot on the cluster map below)<br>
For systems in the New Eden Cluster both a 'geographic' position and a 'schematic' position ("position2D") is provided. The former is the actual position of the solarsystem, used for jump range calculations and the in-game 3D map. The latter is used for the in-game 2D map.

* Relative to the center of a solarsystem. (used by planets, moons, stars, as well as other positions within a solarsystem such as killmails)<br>
The center of a solarsystem is it's star. The star objects themselves do not have an explicit position in the SDE or ESI, as their position is always `[0.0, 0.0, 0.0]`<br>
Expand Down Expand Up @@ -40,6 +41,12 @@ When displayed by the in-game map & most community maps, the mapping convention

![New Eden map](./cluster_map.png)

### 2D 'schematic' Map

The 2D 'schematic' positions follow the same conventions, with the position2D `X` coordinate pointing in the same direction as the 3D position `X` coordinate, and position2D `Y` coordinate pointing in the same direction as the 3D position `Z` coordinate.

![New Eden '2D' diagram map](./cluster_map_2d.png)

### Route calculation

See [Route Calculation](../route-calculation.md) for details how to calculate a route in New Eden.
Expand Down Expand Up @@ -94,9 +101,9 @@ z = z<sub>system</sub> + z<sub>planet</sub>
In 3D rendering or other situations where 64-bit numbers are unavailable, "Floating Origin" techniques can also mitigate this problem.


## Example: 2D map
## Example: 3D map rendered as an image

To draw a 2D map of the universe, the 3D coordinates need to be transformed into 2D positions on an image. The transformation required varies depending on the coordinate system used by the image.
To draw a map of the universe, the 3D coordinates need to be transformed into 2D positions on an image. The transformation required varies depending on the coordinate system used by the image.

This example uses the common "top-left origin" coordinate system widely used in images & 2D graphics. Here the `(0,0)` origin lies in the top-left corner of the image, the X axis points **right** and the Y axis points **down**.

Expand All @@ -110,9 +117,14 @@ These image axes map onto the axes of the universe data as follows:

After this, the coordinates must be moved and resized to fit within the image canvas. This can be done by calculating a bounding box, subtracting the position of the top-left corner of the bounding box from each coordinate, then dividing by width or height of the bounding box. This yields a position in the range 0 to 1, which can then be multiplied by the image width or height to get a final pixel position.

--8<-- "snippets/examples/map-2d-cluster.md"
--8<-- "snippets/examples/map-cluster.md"

The 2D "schematic" positions can be used similarly, with the 3D `Z` coordinate replaced by the 2D `Y` coordinate:

* X<sub>img</sub> = X<sub>eve</sub>
* Y<sub>img</sub> = -Y<sub>eve</sub>

A 2D solarsystem map can be drawn through the same approach, but as the X-axis points in the opposite direction for celestial body coordinates, both the X<sub>eve</sub> and Z<sub>eve</sub> are negated:
A solarsystem map uses different axes; The X-axis points in the opposite direction for celestial body coordinates, both the X<sub>eve</sub> and Z<sub>eve</sub> are negated:

* X<sub>img</sub> = -X<sub>eve</sub>
* Y<sub>img</sub> = -Z<sub>eve</sub>
Expand Down
37 changes: 0 additions & 37 deletions snippets/examples/map-2d-cluster.py

This file was deleted.

48 changes: 48 additions & 0 deletions snippets/examples/map-cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import json
from PIL import Image, ImageDraw # Using 'Pillow' for image drawing.

# Load data from SDE; `system_coordinates` as a list of `(x, y, z)` tuples
system_coordinates = []
with open("./mapSolarSystems.jsonl", encoding="utf8") as f:
for line in f:
system = json.loads(line)
if int(system["_key"]) <= 30_999_999: # "_key" is the solarSystemID; Load only the systems in the New Eden cluster
system_coordinates.append((system["position"]["x"], system["position"]["y"], system["position"]["z"]))


# Image config
IMG_SIZE = 1024
STAR_RADIUS = 1

# Determine bounding-box
xMin, xMax, zMin, zMax = 0,0,0,0
for (x, y, z) in system_coordinates:
xMin = min(xMin, x)
xMax = max(xMax, x)
zMin = min(zMin, z)
zMax = max(zMax, z)

MAP_SIZE = max((xMax - xMin), (zMax - zMin))
ASPECT_RATIO = (xMax - xMin) / (zMax - zMin) # The cluster is not perfectly square, adjust image width to match aspect ratio to avoid the map becoming 'stretched' into a square

img = Image.new("RGBA", (int(IMG_SIZE * ASPECT_RATIO), IMG_SIZE), (0, 0, 0, 255))
draw = ImageDraw.Draw(img)

for (x, y, z) in system_coordinates:
draw.circle(
(
# To convert the coordinates from 3D to pixel positions:
# 1) Subtract the minimum value to set the lowest value to 0.0
# 2) Divide by MAP_SIZE (the difference between max and minimum value) to set the highest value to 1.0
# This places all X coordinates in the range 0.0 - 1.0
# 3) Multiply by IMAGE_SIZE, placing all X coordinates in the range 0.0 to IMG_SIZE, in pixels
(x-xMin)/MAP_SIZE * IMG_SIZE,
# Repeated for the Z coordinate, which is inverted as the map coordinate axis points in the opposite direction as the pixel coordinates.
# Accordingly, the maximum ("least negative") value is subtracted instead
(-(z-zMax))/MAP_SIZE * IMG_SIZE
),
STAR_RADIUS,
fill=(255, 255, 255, 255)
)

img.show()