This is a fairly common math especially in gaming where we all use some sort of abstract grid to line up things nicely or whatever.

All this kind of math does is to treat a normally continuous real space of numbers as integers, or more precisely, as discrete jumps defined by some spacing parameter. You can quickly see that integers are just a special case where this spacing parameter is exactly 1.

So the dividing is what transforms one space into another (in this case, it’s just a line, so 1D “space”), it essentially flexes the original space so that the integers align with whatever your in-between spacing is. The next trick is to cull off the decimal part of the result (aka truncate the result) and this is typically done via **floor**ing, **ceil**ing, or **round**ing. These are three different flavors of converting a decimal point value to an integer.

Floor will nudge toward the nearest integer on the left of the value. Ceil does the opposite. And rounding will nudge it toward the nearest of the two (with some additional rules if it’s exactly in the middle).

jasonboukheir uses FloorToInt method which will also convert the type of the result from `float`

to `int`

as a convenience.

Everything else is really just extra fluff with regard to this specific geometry you’re after.

–

Edit:

Here are some commonly used functions from my libraries

```
// using System;
/// <summary> Rounds down a floating point value to the greatest integer smaller than n. </summary>
static public float floor(float n) => MathF.Floor(n);
/// <summary> Rounds up a floating point value to the smallest integer greater than n. </summary>
static public float ceil(float n) => MathF.Ceiling(n);
/// <summary> Rounds a floating point value to the nearest integer. </summary>
static public float round(float n) => MathF.Round(n);
/// <summary> Returns the fractional part of the floating point value. </summary>
static public float frac(float n) => n % 1f;
/// <summary> Returns the integral part of the number (truncates the fractional part). </summary>
static public float trunc(float n) => MathF.Truncate(n);
/// <summary> Rounds down a floating point value to the greatest step value smaller than n. </summary>
/// <param name="d"> Size of the step interval. No steps if d <= 0. </param>
/// <param name="o"> Optional. Step offset. Default: 0 </param>
static public float floorStep(float n, float d, float o = 0f)
=> d <= 0f? n : d * floor((n - o) / d) + o;
/// <summary> Rounds up a floating point value to the smallest step value greater than n. </summary>
/// <param name="d"> Size of the step interval. No steps if d <= 0. </param>
/// <param name="o"> Optional. Step offset. Default: 0 </param>
static public float ceilStep(float n, float d, float o = 0f)
=> d <= 0f? n : d * ceil((n - o) / d) + o;
/// <summary> Rounds a floating point value to the nearest step value. </summary>
/// <param name="d"> Size of the step interval. No steps if d <= 0. </param>
/// <param name="o"> Optional. Step offset. Default: 0 </param>
static public float roundStep(float n, float d, float o = 0f)
=> d <= 0f? n : d * round((n - o) / d) + o;
```

These `XStep`

variants are particularly useful when it comes to grid-like behavior. I nearly regularly use roundStep in my projects. And you can very easily see what I’ve explained at the top. A value is scaled by the spacing, then rounded to the nearest integer, then scaled back to its original space. This way the input values get **snapped** to some evenly spaced imaginary points. Imagine if `d`

was 1 then it would not scale anything, but `round`

would snap the values to whole numbers. The `o`

argument is used to optionally *offset* the regularity of the snapping to the left or right. This is useful when you want the points to land left or right from the 0, but never on the 0 itself.

If you apply this function to a multi-dimensional coordinate system, you get the grid behavior, and you can very easily change the spacing and offset for all desired axes.

```
[SerializeField] Vector2 _grid;
[SerializeField] Vector2 _offset;
Vector2 GetGridPoint(Vector2 point)
=> new(roundStep(point.x, _grid.x, _offset.x), roundStep(point.y, _grid.y, _offset.y));
void OnDrawGizmos() {
var mouse = ... // capture mouse position
DrawPoint(mouse, Color.cyan);
DrawPoint(GetGridPoint(mouse), Color.magenta);
}
```

Btw `Mathf.FloorToInt`

is just

```
public int FloorToInt(float value) => (int)MathF.Floor(value);
```