Math Help - snapping to points

Ok, I can’t seem to visualize the solution to this:

If you have 4 points in a rectangle shape, with these coordinates:

0,0…4,0

0,4…4,4

if you want a point somewhere in this rectangle to “snap” to then corners of this rectangle, you divide the x coordinate by 4, round it, multiply by 4. Do the same with the Y coordinate.

Now…what about this situation:

…2,0…

0,2…4,2

…2,4…

Instead of needing the coordinates for the corners to snap to, I need to snap to the center of the rectangle sides. The center of the rectangle is NOT a valid point.

I can’t seem to figure out the math to do this. I could probably do some lengthy if statements… (if X is here and Y is here, it’s on this side) type stuff, but it seems like there would be a more elegant solution. Right now, my brain just can’t seem to picture it.
Any help on this?

[Edit] I realize I could easily get the midpoints of the 4 sides, and figure out which one the arbitrary point in square is closest to. Since snapping to the corners is as simple as this:

snapX = Round(originalx /4)*4

snapY = Round(originalY /4)*4

I was hoping for something similar, that didn’t require more complex logic. Don’t know if that is possible though :slight_smile:

This is not really a unity question in any sense, but I’ll answer it anyway, 'cause I’m in a good mood :slight_smile:

not gonna be able to do this without some logic I don’t think, though not sure I would call it COMPLEX logic in any case.

Convert the pos to one relative to the cube center, i.e…

centeredTouch = touchPos - boxCenterPos;

then compare the absolute x and y values, picking the larger one (furthest from center == closest to edge). That’ll tell you if you’re snapping to up/down or to left/right. Then for each case, decide which direction to snap based on the sign of that component’s value.

if (abs(centeredTouch.x)>abs(centeredTouch.y))
{
    if (centeredTouch.x<=0)
        snapPos=leftSnapPos;
    else
        snapPos=rightSnapPos;
}    
else
{
    if (centeredTouch.y<=0)
        snapPos=upSnapPos;
    else
        snapPos=downSnapPos;
}    

this’ll snap to whichever edge of the box you’re closest to in a straight line, which will work out to the same as which center you’re closest to. If you want to specifically ignore the center, you’ll have to add logic for that; in this pseudocode the tie would go to y if x/y are same distance, and up if up/down distances are the same, so a dead center touch would snap to up, and touches directly on the diagonals of the square would snap to up/down.

There may be a pure-math approach that has no conditional logic, but it’s probably going to be more computationally expensive than this.