如何获得最近的网格交叉点?

时间:2014-10-13 13:26:15

标签: c++ sfml

我试图在相对于鼠标的网格上最近的线交叉处画一个圆圈。我从中心向外绘制网格,使用不同的x和y分色。我试图获得正确的坐标,但它关闭了。如何获得正确的坐标?

这是我的代码:

class Grid : public sf::Drawable, public sf::Transformable
{
public:

    Grid(unsigned int Xsep, unsigned int Ysep, unsigned int CanvasW, unsigned int CanvasH);

    virtual ~Grid() {};

    void setFillColor(const sf::Color &color);

    void setSize(unsigned int Xsep, unsigned int Ysep, unsigned int CanvasW, unsigned int CanvasH);

    unsigned int xSep = 0;
    unsigned int ySep = 0;

private:

 virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        // apply the entity's transform -- combine it with the one that was passed by the caller
        states.transform *= getTransform(); // getTransform() is defined by sf::Transformable

        // apply the texture
        states.texture = &m_texture;

        // you may also override states.shader or states.blendMode if you want
        states.blendMode = sf::BlendMode(sf::BlendMode::SrcAlpha, sf::BlendMode::OneMinusDstColor,sf::BlendMode::Add);

        // draw the vertex array
        target.draw(m_vertices, states);
    }

    sf::VertexArray m_vertices;
    sf::Texture m_texture;
};

Grid::Grid(unsigned int Xsep, unsigned int Ysep, unsigned int CanvasW, unsigned int CanvasH)
{

    xSep = Xsep;
    ySep = Ysep;

    m_vertices.setPrimitiveType(sf::Lines);
    m_vertices.clear();

    for (int i=((CanvasW/2)-Xsep); i > 0; i-=Xsep)
    {
        m_vertices.append(sf::Vector2f(i,0));
        m_vertices.append(sf::Vector2f(i,CanvasH));
        m_vertices.append(sf::Vector2f(CanvasW-i,0));
        m_vertices.append(sf::Vector2f(CanvasW-i,CanvasH));
    }

    for (int i=((CanvasH/2)-Ysep); i > 0; i-=Ysep)
    {
        m_vertices.append(sf::Vector2f(0,i));
        m_vertices.append(sf::Vector2f(CanvasW,i));
        m_vertices.append(sf::Vector2f(0,CanvasH-i));
        m_vertices.append(sf::Vector2f(CanvasW,CanvasH-i));
    }

    m_vertices.append(sf::Vector2f(0,CanvasH / 2));
    m_vertices.append(sf::Vector2f(CanvasW,CanvasH / 2));
    m_vertices.append(sf::Vector2f(CanvasW / 2, 0));
    m_vertices.append(sf::Vector2f(CanvasW / 2,CanvasH)); 

}

int RoundNum(int num, int difference)
{
     int rem = num % difference;
     return rem >= 5 ? (num - rem + difference) : (num - rem);
}

sf::CircleShape point(5);
point.setOrigin(point.getRadius()/2,point.getRadius()/2);
sf::Vector2f mousepos = mapPixelToCoords(sf::Mouse::getPosition(*this));
point.setPosition(RoundNum(mousepos.x,grid.xSep),RoundNum(mousepos.y,grid.ySep));
draw(point);

1 个答案:

答案 0 :(得分:0)

我至少看到了两件事情。

首先,将网格线设置为与中心向外均匀间隔。 但是RoundNum(mousepos.x,grid.xSep)会将您的位置捕捉​​到间隔开的网格线 统一来自x为零的地方。据推测,这一点不在其中心 长方形。它在矩形的一角吗?由于矩形的宽度 不是2 * grid.xSep的倍数,与角对齐的网格将偏移 从与角落对齐的网格。对于y坐标也是如此。

编辑以回复评论:解决此类问题的一种方法是从x坐标中减去width / 2,然后将其四舍五入,然后添加width / 2。或者,找到 grid.xSep - ((width/2)%grid.xSep);将该值添加到x坐标,舍入结果,然后减去该值。第二种方式更复杂,但如果x中的x%n为负,则无需考虑会发生什么。当然你也可以用y坐标做类似的事情。

其次,仅当difference为9或10时才有效:

    return rem >= 5 ? (num - rem + difference) : (num - rem);

如果将difference替换为5,它将适用于difference/2的偶数值。 要使其适用于difference(偶数或奇数)的所有值,请替换5(difference + 1)/2

也许值得确认这可以达到你想要的效果:

point.setOrigin(point.getRadius()/2,point.getRadius()/2);

它似乎是正确的,但它很容易检查(只需在已知的网格点(例如中心)绘制CircleShape,这样您也可以确定。