Wednesday, March 29, 2017

Calculating the size of Hyrule in Breath of the Wild

Spoiler warning: This post contains minor spoilers for The Legend of Zelda: Breath of the Wild. If you're very sensitive to spoilers, and you don't want to know anything about the map or characters or Link's abilities in the game, then don't read this.

I bought The Legend of Zelda: Breath of the Wild and I love it! One of the coolest things about it is the massive open world. There's just so much to explore, and you can have hours of fun exploring an area, only to find that it is only a tiny fraction of the whole of Hyrule, which is all entirely open to exploration. I wondered exactly how big the world is, so I made a fairly precise calculation of exactly how big the world is, in real-world units.

If I'm even going to start a task like this, I better have a frame of reference so I can relate the game world with the real world. Luckily there's this minigame in Breath of the Wild.


Branli is a researcher who is interested in learning about "bird people". (I guess he's referring to the Rito.) He is located at the top of Ridgeland Tower. Because of Link's ability to paraglide, he thinks that Link is a bird-man. If you pay him a deposit of 20 rupees, he will have you glide off the tower, and measure the distance you travel. (If you're wondering, he does pay you back if you go far enough.) Fortunately for me, the distance is measured in meters, and we can see it live, as Link is gliding.


So when I reached 500 m (actually 500.1 m but whatever), I immediately paused the game to look at the map.


Above is the map at the most zoomed out level. (I've annotated it to point out the tower and Link.) Wow, you can see that 500 meters is pretty small when compared to the whole of Hyrule! In fact, the above map can't even show the entirety of Hyrule, just the north part! I took another screenshot where the map shows the south part:


I don't like dealing with 2 images, so I used image editing magic to combine them into a single image:


Now THIS is the entirety of Hyrule. Neat! From this point, I used Web Plot Digitizer to find the total size. This cool web app lets you click on points, and it tells you their coordinates. It even scales pixels into arbitrary units, if you have a reference (which I have, thanks to Branli!).

First I uploaded my image with the entire Hyrule map. This tool can handle all sorts of plots, but I chose "Map with Scale Bar". Well, in this case there is no actual scale bar on the map, but the 500 meters between the tower and Link is effectively a scale bar.

Then I had to click 2 points to use as a scale to calibrate the axes. Here I clicked on the tower I jumped from, and on Link's current location, which is 500 meters away. Then I entered the distance and the unit. I entered it in kilometers because that's probably a better unit to measure Hyrule.


Now I can pick any number of points, and then view their coordinates in km. I chose the top left corner of the map, and the bottom right corner. The map fades out at the edges, so I tried to choose the points where the fading started.


Finally we can calculate the east-west distance and north-south distance of Hyrule by subtracting these coordinates. The width is about 10.271 km by 7.905 km. Approximately 10 km by 8 km. Amazing!

Friday, February 10, 2017

Introducing a new mathematical notation for functions

How it's usually done

I've always been quite unsatisfied with the standard mathematical notation for functions. Typically, if you wanted to define functions, you would say something like this:

I want to emphasize the difference between f and f(x), since I think it is worth noting. f represents the function, whereas f(x) represents the value you would get if you plug in x into the function. Another way of seeing this is that in this example, the "type" of f is "function", whereas the "type" of f(x) is "real number". Of course, f(x) doesn't mean anything unless you already know what x means.

So, with this in mind, you'll notice that the above notation, which was supposed to define the function f, only told us what would happen if you plugged in some number x. A real definition should have the symbol to be defined (in this example f) by itself on the left hand side, and the thing it represents on the right hand side. But here, f is not by itself on the left hand side. Since we lack the notation to say what f is, we introduce a new variable x and say what f(x) is. The implicit idea behind this is that there is only one function that transforms the input variable x into the output specified by that expression. This makes sense, but it is really an indirect workaround for the lack of actual function-definition notation.

As an (admittedly contrived) analogy, consider what we would do if we lacked the digit "5" in our notation, but we had all other digits. What if we wanted to define a number n to have the value five? We might resort to something like "Let x+1=6". Notice that this gives you enough information to know what x is, but is too indirect.

The standard way of defining functions also has some limitations of convenience. For example, it is not easily pluggable into expressions that use it. As an example, consider the function composition notation.

In case you need a refresher, function composition is when you create a new function by applying one function, and then another. In this case, the function f○g represents the result of applying g first, then f.

Let's make another analogy with numbers. Let's say you know already that a=3 and b=2. When you encounter an expression like a+b, you can replace the symbols with what they represent, resulting in the equivalent expression 3+2. Now what happens when we try this with the function composition above. We know what f and g are. But we don't have expressions for them! There's nothing we can plug in. We can try confusing f(x) with f. Then we the nonsensical notation:

It's not clear here how this should be interpreted. This is supposed to be true for all x. But if we plug in x=3, we get this weird result that has obviously lost all meaning:

Clearly, we need a better way of writing functions.

My way

I propose that we write the above function definitions like so:

Now f and g are defined directly. The function consists of curly braces with two clauses separated by a colon. The first clause introduces a temporary symbol to represent any arbitrary value in the domain, and the second clause is an expression in terms of this symbol showing the procedure of transforming the input value into the output.

If you have seen "set-builder notation" before, you might recognize it as similar to the notation that I am introducing.

In fact, the only difference is that instead of a value in the second clause of set-builder notation, there is a condition. If you view a condition as a boolean value (AKA a value that is either true/false), then a set is nothing but a function that results in a true or false value. So, these notations are compatible. If you're into set theory, you might already think of sets in your head as functions that result in booleans.

Let's see how we can plug the functions into expressions:

See how clear this is? You can see where the functions are really easily using this notation, and there is no "type confusion" between functions and numbers, so to speak.

Bonus features

Derivatives

With standard notation, you would probably write something like this:

Here, the function's independent variable is weirdly embedded within the differential operator. Also, the resulting function cannot be used in an expression. Even something like evaluating it at a x=3, which should be as simple as putting (3) at the end, is not easy. There are a few common special-purpose notations to solve this very specific issue:

But this is not required if we use my notation for functions. The derivative operator, in essence, takes a function and results in a function. So it can itself be viewed as a higher order function, let's call it D.


If you want, you can express the definition of the derivative like this:

Fourier Transform

This is how you might have seen the Fourier transform definition. It was probably explained to you in words (as opposed to math) that capital F is the transform of lowercase f.
(Note: this is the way I was taught it. It uses j as the imaginary unit, and there is no 2π in the forward transform. If you're used to a different definition, some of the properties/pairs are slightly different)

There was no good way to write a transform pair, so one was invented for that overly-specific purpose:

This notation relies on the "magic variables" t and ω to be the independent variables of the two functions.

With my notation, the Fourier transform may be expressed as a higher order function FT like this:

And a transform pair can be expressed like:

Wednesday, January 25, 2017

Generating a cube in Python

Check out this cool image!
enter image description here

I generated it with the following python code:

import numpy as np
import matplotlib.pyplot as plt
plt.imsave(
    'outfile.png',
    np.histogramdd(
        np.dot(
            np.random.random((10000000,3))-.5,
            np.array([[0.4,0],[0.1,0.4],[-0.2,0.3]])),
        bins=(500,500),
        range=((-.5,.5),(-.5,.5)))[0],
    cmap='gray')

How it works

The image consists of 10 million random 3D points which have been projected into 2D, and then turned into an image.

I start with generating 10 million random 3D points where each component can vary uniformly from -0.5 to 0.5. Notice that these points will form a 1x1x1 cube centered at the origin. This is done with the line np.random.random((10000000,3))-.5. This is a 10000000x3 numpy array.

In order to turn these 3D points into 2D points, I use an isometric projection. An isometric projection is not as realistic as a perspective projection, but it is simpler to compute. All that needs to be done is a linear projection (or an affine projection, in case you don’t want the origin to project on the origin). In this case, the center of the projected cube will be at the origin. To perform the isometrix projection, I multiply the 10000000x3 matrix of points on the right with the 3x2 matrix np.array([[0.4,0],[0.1,0.4],[-0.2,0.3]]). I chose this matrix arbitrarily, just so that the picture looks nice at the end. This now results in a 10000000x2 matrix, containing 10 million 2D points, representing a projected cube centered at the origin.

Now I have a bunch of points, but what I really need in order to make an image is a 2D array of pixel intensities. To obtain this, I used np.histogramdd, which computes a multidimensional histogram of the data we computed. Pretty much, I am partitioning the 2D space from -0.5 to 0.5 in each dimension into 500x500 “bins”, and counting how many points in each bin. Each bin will then correspond to a pixel, and the pixel intensity should be proportional to the count of its bin.

Finally, I use plt.imsave to save the image as a PNG. Neat!

Written with StackEdit.