• What is your GameDev Story?

Archived

This topic is now archived and is closed to further replies.

Snap to grid problem!

This topic is 5555 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi all! I''m creating an editor for my game. The editor has several modes including line drawing mode and polygon mode (like MSPaint''s polygon mode). Anyway, I''m allowing the user the option to use snap-to-grid, which snaps the endpoint of the line (that the user drew) to the nearest gridpoint. Here''s my grid drawing function:

//DrawGrid

void CObliteration::DrawGrid()
{
int offsetX = -(editorScreenX%16);
int offsetY = -(editorScreenY%16);

for (int x=0;x<38;x++)
{
for (int y=0;y<38;y++)
{
//	RECT dest = {(x*32)-1+offsetX,(y*32)-1+offsetY,

//(x*32)+1+offsetX,(y*32)+1+offsetY};

//	SpriteIndex[SI_PIXEL].Draw(dest,COL_BLACK,0);

DrawPixel((x*16)+offsetX,(y*16)+offsetY,COL_BLACK);

}
}

}

and here is my snap to grid function:

//snap to grid

void CObliteration::SnapToGrid(POINT2D* p)
{
if (!editorSnapToGrid)
return;

int dx = p->x%16;
int dy = p->y%16;

int ex = editorScreenX%16;
int ey = editorScreenY%16;

p->x -= dx;
p->y -= dy;

if (dx >= 8 && ex < 8)
p->x += 16;
if (dy >= 8 && ey < 8)
p->y += 16;

}

editorScreenX and editorScreenY are the coordinates of the "camera" of the editor (current position in the editor world). POINT2D* p is the mouse position, (relative to the client, not yet transformed in world space) The problem is, at editorScreenX and editorScreenY coords like (360,-276), it snaps the POINT2D not to the nearest gridpoint, but to the greater gridpoint (for example if the point is close to point 1 on the left, it snaps to point 2 on the right, whereas it is supposed to snap to point 1, because it is closer to it). Thanx in advance! Ciph

Share on other sites
I''m in a very big rush so I could not read your entire post, nor do I know if this will help you but..

If I want to take a point and snap it to a grid, I simply do this (psuedo-code):

X = int(mouseX / tileWidth) * tileWidthY = int(mouseY / tileHeight) * tileHeight

Share on other sites
that''s the quick and easy way - but it doesn''t snap a point to the nearest tile - it only snaps it to the next lowest "integer" tile.

For example, two gridpoints with points (0,0), and (32,0)

It would snap (28,0) to (0,0), not (32,0), as it should.

Share on other sites

X = int((mouseX / tileWidth)+tileWidth/2) * tileWidth
Y = int((mouseY / tileHeight))+tileHeight/2) * tileHeight

This will round at 0.0 to 0.49999 -> inferior and 0.5 to 0.9999 ->superior

[edited by - ph0ngwh0ng on August 15, 2003 3:13:56 PM]

Share on other sites
Sorry, doesn''t work.

lol.

Share on other sites
p->x = int((p->x + 8) / 16) * 16; // add half a square, then round downp->y = int((p->y + 8) / 16) * 16; // ditto

will snap 'p' to the nearest grid point (assuming gridsize = 16)
for other size grids, adjust the 8 and 16.

EDIT:
Following the brackets through:
first, add half a tile in each direction. if x = 3, it will become 11, let the int function/cast round it down, it ends up as 0, the nearest point
if x = 10, it becomes 18, and int will round it to 16, the next grid point.

HTH

[edited by - blacksheep on August 15, 2003 4:43:42 PM]

Share on other sites
First of all I don''t see the point of the whole ex & ey part - why should the camera position affect where to snap the point? Normally the grid is an absolute thing, not relative to the current view position.

Anyway I think your problem comes from the sometimes unintuitive results of using % with negative numbers. Take for example the point (0,-28). It should be snapped to (0,-32) since that''s the closest multiple of 16. With your algorithm here''s what happens:

int dy = -28 % 16; // the result will be -12 not 4
p->y -= dy; // the result will be -16 not -32

if (dy >= 8) ... // not true since dy == -12

So now it has snapped to the higher point (0,-16) instead of the closer point (0,-32).

Share on other sites
I use a function called RInt (Round Int) to make sure that it snaps to the right grid point. This is it:
int RInt(float u){        int i = (int)u;    float f = u - i;    if(f >= 0.5) i++;    return(i);    }
This is my code for snapping to the grid:
void SnapToGrid(vec3_t v1, float fGridSize){        v1[0] = RInt(v1[0] / fGridSize) * fGridSize;    v1[1] = RInt(v1[1] / fGridSize) * fGridSize;    v1[2] = RInt(v1[2] / fGridSize) * fGridSize;    }
v1 can be any point, but I usually get my points from OpenGL with gluUnProject(). You could also get points by adding the camera movement on to the mouse position.

It works like this:
 |      |     |      |-0------0-   -0------0- | *    |     |      |  |      |     |      |  |      |     |    * | -0------0-   -0------0- |      |     |      |
The asterisks are mouse clicks. Without RInt, both points are snapped to the grid point in the top left hand corner. RInt compensates for the fact that integer casting doesn't round down...

Coding Stuff ->  [ iNsAn1tY Games | DarkVertex | How To Do CSG | Direct3D Vs. OpenGL | Google ]
Fun Stuff    ->  [ Evil T-Shirts | Stick-Based Comedy | You're Already Here | The Best Film Reviews ]

[edited by - iNsAn1tY on August 15, 2003 5:26:08 PM]

Share on other sites
yeah i removed the ex and ey part. so i should take the abs of dx and dy when comparing then to 8?

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 13
• 9
• 9
• 15
• Forum Statistics

• Total Topics
634073
• Total Posts
3015343
×