GridMath – progress report

A couple of days ago I wrote about kicking-off a small library project called GridMath. Although I create it to my own ends and for a specific purpose, I also want it to become a worthy dependecy. Especially when I saw the first version getting some downloads.

GridMath 0.1 sucks

First, I fixed a rather embarassing bug.

You see, when mapping from real coordinates to grid coordinates there are a couple of common conventions. One is rounding to the nearest number. I did not like this approach because .5 requires somewhat arbitrary choice which may be hard to remember.

Instead, I chose that full interval from for example 1.0 to 2.0 (exclusive) will map to 1 in grid coordinate system. Hey, I think, looks like I can just cast floating point values to integers. This way, the floating part gets truncated and we’re home.

Right? Wrong!

It doesn’t work so well for negative values. Take 0.2 for instance. It maps to 0 in my grid coordinate system. What about -0.2 then? Well, cast to int gives 0 as well.

Silly me.

Now I’m doing Math.Floor() on real values. I actually added RealToGrid utility class which does this mapping. I could just Math.Floor() everywhere, but having a ‘mapper’ class feels so much more professional.

Distance and Depth in GridMath

One feature I added is measuring Distances and Depths for intervals.

The idea with Distance is that if the thing is to the right of the interval it returns positive value, and a negative value if it is to the left. The thing can be a coordinate or another interval. In the latter case we’re measuring distance to its nearest end. The value signifies how far you’d need to translate your interval to touch – or be right next to – the target. If it already does touch, contain or overlap with target, the result is 0. This basically means that no translation is necessary – we’re near enough!

public int Distance(int coordinate)
{
    if (Contains(coordinate) || Touches(coordinate)) return 0;
    if (coordinate > MaxExcl) return coordinate - MaxExcl;
    return coordinate - (Min - 1);
}

public int Distance(GridInterval other)
{
    if (Overlaps(other) || Touches(other)) return 0;
    return other.Min > Max ? Distance(other.Min) : Distance(other.Max);
}

Depth works in a similar fashion. It tells how far left or right the interval must be moved to touch the target and not contain it.

What about bounding boxes

I didn’t yet write corresponding functionality for GridBoundingBoxes. First, I’ll need to implement measuring distance between two-dimensional grid coordinates. There are three methods of doing this, all depicted in this nice blog post. Then, I need a method to find a point in the bounding box to the target. Coming soon!

Putting the math into GridMath

Well, not so much math actually, just some wee more complex algorithms. I also wrote utility classes for both GridIntervals and GridBoundingBoxes. I named them just so. Those classes focus on heavy lifting operations on collections of intervals and boxes. I’ll write about those in a separate post.

Leave a Reply

Your email address will not be published. Required fields are marked *