Godot Version
4.3
Question
I need help writing an algorithm that finds the closest number up or down to a parameter that is divisible evenly by 16 but not 32
4.3
I need help writing an algorithm that finds the closest number up or down to a parameter that is divisible evenly by 16 but not 32
I believe you can use binary operators.
func is_16_not_32(input: int) -> bool:
# any 1-8 place is not divisable by 16
var div_16: bool = input & 0b01111 == 0
# similarly, a 16ths place means not divisable by 32
var not_32: bool = input & 0b10000 != 0
return div_16 and not_32
Sorry this only deduces if it is a valid number.
A similar binary operating function would have a strange rounding behavior if that is okay.
func make_grid_16_not_32(input: int) -> int:
var div_16: int = input & 0b01111
var no_16: int = input ^ div_16
var no_32: int = no_16 | 0b10000
return no_32
Basically i am spawning rooms and they end up not aligned to my tilemap. I need to snap the x position to the closest 16 but not 32 if it has an odd length and 32 if its even same for the Y.
I got close using snapped but you cant use it independently on the x and y and it doesnt account for 32 also being a multiple of 16.
Then you can use the first part of that function for everything, and the second part for your extra conditions.
if length & 0b1 == 0: # even
pos.x = make_grid_16(pos.x)
else: # odd
pos.x = make_grid_16_not_32(pos.x)
I ended up coming up with this. it works but I can’t help but feel like I could do the same in less code it just seems like a lot for a relatively trivial function.
public static Vector2I GridSnap(Vector2I position, int width, int height, int cellSize)
{
int newX = int.MinValue;
int newY = int.MinValue;
if (width / cellSize % 2 != 0) {
for (int upX = position.X; upX < position.X + cellSize; upX++) {
if (upX % (cellSize / 2) == 0 && upX % cellSize != 0) {
newX = upX;
break;
}
}
for (int downX = position.X; downX > position.X - cellSize; downX--) {
if (downX % (cellSize / 2) == 0 && downX % cellSize != 0) {
if (newX - position.X > position.X - downX) {
newX = downX;
break;
}
}
}
}
else {
for (int upX = position.X; upX < position.X + cellSize; upX++) {
if (upX % cellSize == 0) {
newX = upX;
break;
}
}
for (int downX = position.X; downX > position.X - cellSize; downX--) {
if (downX % cellSize == 0) {
if (newX - position.X > position.X - downX) {
newX = downX;
break;
}
}
}
}
if (height / cellSize % 2 != 0) {
for (int upY = position.Y; upY < position.Y + cellSize; upY++) {
if (upY % (cellSize / 2) == 0 && upY % cellSize != 0) {
newY = upY;
break;
}
}
for (int downY = position.Y; downY > position.Y - cellSize; downY--) {
if (downY % (cellSize / 2) == 0 && downY % cellSize != 0) {
if (position.Y - newY > downY - position.Y) {
newY = downY;
break;
}
}
}
}
else {
for (int upY = position.Y; upY < position.Y + cellSize; upY++) {
if (upY % cellSize == 0) {
newY = upY;
break;
}
}
for (int downY = position.Y; downY > position.Y - cellSize; downY--) {
if (downY % cellSize == 0 ) {
if (newY - position.Y > position.Y - downY) {
newY = downY;
break;
}
}
}
}
return new Vector2I(newX,newY);
}
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.