Friday, November 25, 2016

The art of note taking

Over the years, my note taking has evolved and I developed a system which consists of
  • Point of interest: Similar to ordinary bullet points, usually a dot or an asterix.
  • Action item: Things that I have to do. I encircle a point of interest to mark it as an action item.
  • Done: A check to the left of an action item means that I have completed it.
  • Doodles: Help me concentrate and relax. For the concept of "relaxed concentration", see The Inner Game of Tennis.
At work I copy my handwritten notes to OneNote and throw away the physical paper. For personal stuff, I copy them to Google Drive. Below is an example:

Listening to:

Algorithms in Save My Cheese

In this post, I will go into the algorithmic details of Save My Cheese. The game consists of several sub-problems:
  1. Drag and snap shapes.
  2. Calculate path from where the mouse is to cheese location. Pathfinding has to take obstacles (unpassable cells) on map into account.
  3. Update map when user places a piece in its place, i.e. make that portion of map unpassable so that a new path to cheese might be needed.

Thursday, November 24, 2016

Converting a desktop game to a web app

Two years ago, I wrote a simple desktop game, Save My Cheese, mainly to explore the A* pathfinding algorithm. In the game you are trying to block the path of mice by puzzle pieces and prevent the mice from reaching the cheese. When you finish the puzzle before the mice reach the cheese, you finish that level.

Monday, November 21, 2016

Geoid

Recently I was testing Matlab2012a geoid functions of which there are two: geoidheight (in Aerospace Toolbox) and egm96geoid (In Mapping Toolbox). I wrote the following script to check if there is a difference between these two function results for the same inputs (takes about half an hour to run):
clc; clear all;
[NVec,refvec] = egm96geoid(1, [-89.75  89.75],[-180 180]);
i = 0;
for lat_deg = -89:89
    fprintf(1, 'lat_deg = %1.1d\n', lat_deg);
    for lon_deg = 0:360
        i = i+1;
        N1_m(i) = geoidheight(lat_deg, lon_deg); %#ok<*SAGROW>

        N2Linear_m(i) = ltln2val(NVec,refvec,lat_deg,lon_deg,'bilinear');
        N2BiCubic_m(i) = ltln2val(NVec,refvec,lat_deg,lon_deg,'bicubic'); %to check if interpolation method makes any difference
    end
end
diff1 = N1_m-N2Linear_m;
diff2 = N2BiCubic_m-N2Linear_m;
subplot(2,1,1)
plot(diff1)
ylabel('diff1')
grid on
subplot(2,1,2)
plot(diff2)
ylabel('diff2')
grid on

As you can see from the plot, the difference between the two functions (diff1) can be as high as 7m! I checked the results with the zip files from NASA EGM96 and found that geoidheight is within 0.01m. This means that there is something wrong with egm96geoid or ltln2val.

Conclusion: Use geoidheight to get geoid offsets. Do not assume that Matlab's functions are correct and ABT (Always be testing). This error seems to be fixed in Matlab 2014 and later versions.

Saturday, November 05, 2016

My software development cycle

When developing software, after getting the overall customer requirements, I first design a little bit, then add some features, fix bugs, then do refactoring and then repeat. While refactoring, I do not attempt to fix bugs or update the overall design. When I see a serious (i.e. more than a days work) bug or the need to update the design of some part, I write it down to Jira. That way I am not distracted from what I do for short term and do not loose my ideas for the long term. I call this the "zoom-in, zoom-out cycle".


GSON

I needed to use GSON to create a JSON string to serialize an object. It is quite easy for simple objects but if your object has fields with NaN values or lists of another class type, it gets a little complicated. After I solved all these problems, the final form of GSON call was:
Gson gson = new GsonBuilder().registerTypeAdapter(MyObj.class, new MyGSONTypeAdapter()).serializeSpecialFloatingPointValues().excludeFieldsWithModifiers(java.lang.reflect.Modifier.TRANSIENT).create();
String jsonStrToSave = gson.toJson(myObj);
Details:
  • GSON does not generate data for
    • private fields without public set/get.
    • null objects
  • To include NaN in JSON string you have to call serializeSpecialFloatingPointValues().
  • To save static fields or to exclude fields, you add the transient keyword to class's field definition and call excludeFieldsWithModifiers(Modifier.TRANSIENT).
  • If your class has lists of other objects, you might get stack overflow error. One way to solve it is to define and register an adapter class. Example:
/**
* GSON type adapter class to solve stack overflow error.
* Assumes you have a class called MyClass with getVal() method.
*/
class MyGSONTypeAdapter <T extends MyClass> extends TypeAdapter {

   @Override
   public void write(JsonWriter writer, T t) throws IOException {
       if (t == null) {
           writer.nullValue();
       } else {
           writer.value(t.getVal());
       }
   }

   @Override
   public T read(JsonReader reader) throws IOException {
       double val = reader.nextDouble();
       return (T) new MyClass(val);
   }
}

Tuesday, November 01, 2016

Understanding vs. Explaining

Understanding something is much easier than explaining it. The next time you are about to complain that someone does not understand what you are talking about, ponder how you could explain the topic better. It is also much easier to change your own behaviour than other's.