如何实现Snap to grid [英] How to implement Snap to grid

查看:182
本文介绍了如何实现Snap to grid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用drawBackground方法实现了网格现在想要实现对它的快照行为。但无法弄清楚如何实施。每个实体都有不同的类。



我有代码在cadGraphicsScene.cpp中绘制网格。它如下:



  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( )));

// 绘制网格。
const int firstLeftGridLine = realLeft - (realLeft%gridSize);
const int firstTopGridLine = realTop - (realTop%gridSize);
QVarLengthArray< QLine,100>线;

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(QPolor(QColor( 220 220 220 ), 0 0 )) ;
painter-> drawLines(lines.data(),lines.size());

// 绘制轴。
painter-> setPen (QPen(Qt :: lightGray, 0 0 ));
painter-> drawLine( 0 ,realTop, 0 ,realBottom);
painter-> drawLine(realLeft, 0 ,realRight, 0 );
}



我希望我的项目只能在网格点绘制。意味着我应该只能在gridview中的任何其他网格点上绘制任何东西。

解决方案

首先确定你的大小网格和每个网格线之间的距离。例如,100个单位高的网格每10个单位可以有一条线。因此,如果用户试图为一个项目进行定位,您只需要计算当前位置的最近网格线并将其捕捉到该点。 X轴也一样。





所以你知道你的第一个网格线的位置,以及每一行是 gridSize 上的像素。当你需要将一个项目放入网格时,你会捕获鼠标x和y(不知道你是如何在Qt中那样做的)。然后你只计算它最接近的网格线,例如:

  if (mouseX< realLeft || mouseX> realRight)
throw 鼠标外网格; // 错误的位置
mouseX - = realLeft; // 使其相对于网格的开始
int offset = mouseX%gridSize; // 偏移到最近的网格线
if (offset>(gridSize / 2 )) // 在行之间超过一半?
mouseX + = gridSize - offset; // 移至下一个网格线
else // 不到一半?
mouseX - = offset; // 移至上一页



[/编辑]


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:

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.

解决方案

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:

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]


这篇关于如何实现Snap to grid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆