SFML community forums

Help => General => Topic started by: LordNani on May 27, 2019, 11:54:37 pm

Title: Dotted line instead of normal
Post by: LordNani on May 27, 2019, 11:54:37 pm
Hello fellas! I am working on Paint 2.0 project which is supposed to be simple yet WORKING graphics editor, using sfml. Yesterday I have encountered the problem which I still can't fix.
I am implementing Pencil tool, but instead of creating normal smooth line it draws dotted and separated ones.
At first, I just made it with drawPixel function but right now I am using Vertices to make lines based on the previous mouseMoved register. In both cases, I get the same scenario.
Here is the function call.
while (mainWindow.pollEvent(event)) {
      if (event.type == sf::Event::Closed)
        mainWindow.close();
      else if ((event.type == sf::Event::MouseMoved) &&
               sf::Mouse::isButtonPressed(
                   sf::Mouse::Left)) // MouseMoved and leftClickHeld
      {
        switch (currentTool) {
        case 0: {
          vecLine =
              drawPencil(mainWindow, currentColor,
                         sf::Mouse::getPosition(mainWindow), thickness, 0);
          break;
        }
        }
      } else if (event.type == sf::Event::MouseButtonPressed) {
        switch (currentTool) {
        case 0: {
          vecLine =
              drawPencil(mainWindow, currentColor,
                         sf::Mouse::getPosition(mainWindow), thickness, 1);
          break;
        }
        case 1: {
          vecLine = drawLine(mainWindow, currentColor,
                             sf::Mouse::getPosition(mainWindow));
          break;
        }
        }
 
And here is the function that draws lines

std::vector<std::pair<sf::Vertex, sf::Vertex>>
drawPencil(sf::RenderWindow &mainWindow, sf::Color color,
           sf::Vector2i currentPos, unsigned int thickness, int mode) {
  if (thickness == 0) {

    if (mode == 1) {
      line[0].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
      line[1].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
      line[0].color = color;
      line[1].color = color;

    } else {
      if (firstPoint) {
        line[0].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
        line[1].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
        line[0].color = color;
        line[1].color = color;
        firstPoint = false;
      } else {
        line[1].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
        firstPoint = true;
        vecLine.push_back(std::make_pair(line[0], line[1]));
      }
    }
    return vecLine;
  } else {
  }
}

Int mode is to deny lines that could be drawn just by clicking and not dragging.

I suspect it's connected with MouseMoved update rate
Title: Re: Dotted line instead of normal
Post by: eXpl0it3r on May 28, 2019, 12:47:46 am
What you want to do is save the last mouse position and on the next mouse moved event, take the last and current mouse position and connect them with a line.

Currently you're taking twice the current position of the mouse to draw a "line".
Title: Re: Dotted line instead of normal
Post by: LordNani on May 28, 2019, 11:33:12 am
I am not sure, but I think I am saving the previous mouse location.
1)When LMB is pressed, it calls drawPencil in mode 1, so it only registers the mouse pos as the "origin" point of the line
2)When the mouse is moved, it calls drawPencil in mode 0, therefore line's when it calls it for the first time, origin of the line is set to currentPos, when the drawPencil called for 2 time it passes the currentPos again
and the line's final point is set
Title: Re: Dotted line instead of normal
Post by: LordNani on May 29, 2019, 12:59:44 pm
FOR THOSE WHO WANT TO FIX.

new code
if ((event.type == sf::Event::MouseMoved) &&
               sf::Mouse::isButtonPressed(
                   sf::Mouse::Left)) // MouseMoved and leftClickHeld
      {
        switch (currentTool) {
        case 0: {
          vecLine =
              drawPencil(mainWindow, currentColor,
                         sf::Mouse::getPosition(mainWindow), thickness, 0, prevPos);
                  prevPos = sf::Mouse::getPosition(mainWindow);
          break;
        }
        }
      } else if (event.type == sf::Event::MouseButtonPressed) {
        switch (currentTool) {
        case 0: {
          vecLine =
              drawPencil(mainWindow, currentColor,
                         sf::Mouse::getPosition(mainWindow), thickness, 1, prevPos);
          break;
        }
        case 1: {
          vecLine = drawLine(mainWindow, currentColor,
                             sf::Mouse::getPosition(mainWindow));
          break;
        }
        }
      } else if (event.type == sf::Event::MouseButtonReleased) {
                  switch (currentTool) {
                  case 0: {
                          vecLine =
                                  drawPencil(mainWindow, currentColor,
                                          sf::Mouse::getPosition(mainWindow), thickness, 3, prevPos);
                          break;
                  }
                  }
        canvas.update(mainWindow);
          }

and the draw pencil is
drawPencil(sf::RenderWindow& mainWindow, sf::Color color,
        sf::Vector2i currentPos, unsigned int thickness, int mode, sf::Vector2i prevPos) {
        if (thickness == 0) {
                if (mode == 1) {       
                        line[0].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
                        line[0].color = color;
                        line[1].color = color;
                       
                }
                else if (mode == 0) {

                        line[1].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
                        line[0].color = color;
                        line[1].color = color;
                        vecLine.push_back(std::make_pair(line[0], line[1]));
                        line[0].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
                       

                }
                else {
                                line[1].position = sf::Vector2f(sf::Mouse::getPosition(mainWindow));
                               
                                vecLine.push_back(std::make_pair(line[0], line[1]));
                        }
                return vecLine;
        }