Click here to Skip to main content
15,885,914 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have implemented grid using drawBackground method now want to implement snap behaviour to it. But unable to figure out how it can be implemented. I have different classes for each entity.

I have code to draw grid in cadGraphicsScene.cpp. It is as follows:

C#
void CadGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
{
    const int gridSize = 50;
    const int realLeft = static_cast<int>(std::floor(rect.left()));
    const int realRight = static_cast<int>(std::ceil(rect.right()));
    const int realTop = static_cast<int>(std::floor(rect.top()));
    const int realBottom = static_cast<int>(std::ceil(rect.bottom()));

    // Draw grid.
    const int firstLeftGridLine = realLeft - (realLeft % gridSize);
    const int firstTopGridLine = realTop - (realTop % gridSize);
    QVarLengthArray<QLine, 100> lines;

    for ( x = firstLeftGridLine; x <= realRight; x += gridSize)
        lines.append(QLine(x, realTop, x, realBottom));
    for ( y = firstTopGridLine; y <= realBottom; y += gridSize)
        lines.append(QLine(realLeft, y, realRight, y));
    qDebug()<<x<<y;

    painter->setPen(QPen(QColor(220, 220, 220), 0.0));
    painter->drawLines(lines.data(), lines.size());

    // Draw axes.
    painter->setPen(QPen(Qt::lightGray, 0.0));
    painter->drawLine(0, realTop, 0, realBottom);
    painter->drawLine(realLeft, 0, realRight, 0);
}

I want that my items should be drawn at grid points only. Means I should be able o draw anything only at the grid points not anywhere else in graphicsview.
Posted
Updated 29-Nov-14 1:12am
v2

1 solution

First decide on the size of your grid and the distance between each gridline. For example a grid that is 100 units high could have a line each 10 units. So if the user is trying to poition an item you just need to calculate the nearest gridline to the current position and snap it to that point. The same goes for the X-axis.

[edit]
So you know the position of your first gridlines, and that each line is gridSize pixels on from that. When you need to drop an item into the grid you capture the mouse x and y (not sure how you do that in Qt). Then you just calculate which gridline it is nearest to, something like:
C++
if (mouseX < realLeft || mouseX > realRight)
    throw "mouse outside grid";    // bad location
mouseX -= realLeft; // make it relative to start of grid
int offset = mouseX % gridSize; // offset to the nearest grid line
if (offset > (gridSize / 2)) // more than half way between lines?
    mouseX += gridSize - offset; // move to next gridline
else  // less than half way?
    mouseX -= offset; // move to previous

[/edit]
 
Share this answer
 
v3
Comments
Member 11238051 29-Nov-14 5:07am    
The problem is coming that how should I calculate the nearest grid position?
Richard MacCutchan 29-Nov-14 5:19am    
Simple maths: you know the mouse position, so it's just the difference between the mouse position and the two gridlines. The smaller difference tells you which is nearest.
Member 11238051 29-Nov-14 6:49am    
Actually I am unable to implement this thing. Can you explain e with the help of small running example
Richard MacCutchan 29-Nov-14 7:02am    
Without knowing the context and what it is that you are trying to snap, it is difficult to suggest any code. A better idea would be for you to update your question and show the code at the point where you want the snap to occur, and we can then make some suggestions.
Member 11238051 29-Nov-14 7:12am    
I have updated my question with the code. Please help me to solve it out.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900