Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::CircleShape getPosition() returns big number  (Read 6991 times)

0 Members and 1 Guest are viewing this topic.

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #15 on: May 27, 2019, 10:10:00 am »
So it's been a long time. Not because of how hard I found this to be, but rather because of how long I haven't programmed in. Anyways I've pretty much gotten it working, using asin to calculate the angle instead of atan that you recommended me, but it doesn't matter as all trigonometric functions would lead to the same result. I have a problem tho. When drawing lines in the Y coordinate its very smooth and behaves as it should, but when on the X it gets jittery sometimes individual dots are not connected and overall has too many corners and ridges(see pictures - second one is without the dots being drawn).

Code:
#include <SFML/Graphics.hpp>
#include <cmath>
#include <iostream>

int pythagoreanTheorem(int a, int b)
{
    int c = sqrt((a * a) + (b * b));

    return c;
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(1920, 1080), "Test");

    sf::Event event;

    std::vector<sf::CircleShape> circles;
    std::vector<sf::RectangleShape> lines;

    sf::Vector2f mouseCoords = window.mapPixelToCoords(sf::Vector2i(sf::Mouse::getPosition(window))), oldMouseCoords = mouseCoords;

    while(window.isOpen())
    {
        mouseCoords = window.mapPixelToCoords(sf::Vector2i(sf::Mouse::getPosition(window)));

        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
            {
                window.close();
            }

            if(event.type == sf::Event::MouseMoved)
            {
                sf::CircleShape circle;
                circle.setRadius(20);
                circle.setPosition(mouseCoords);
                circle.setOrigin(circle.getRadius(), circle.getRadius());
                circle.setFillColor(sf::Color::Black);

                circles.push_back(circle);

                if(circles.size() > 1)
                {
                    sf::RectangleShape line;

                    line.setSize(sf::Vector2f(circles[circles.size() - 2].getRadius() * 2, pythagoreanTheorem(circles[circles.size() - 1].getPosition().x - circles[circles.size() - 2].getPosition().x, circles[circles.size() - 1].getPosition().y - circles[circles.size() - 2].getPosition().y)));
                    line.setOrigin(line.getSize().x / 2, 0);

                    //calculate Sine
                    double idk = (circles[circles.size() - 1].getPosition().x - circles[circles.size() - 2].getPosition().x) / pythagoreanTheorem(circles[circles.size() - 1].getPosition().x - circles[circles.size() - 2].getPosition().x,
                           circles[circles.size() - 1].getPosition().y - circles[circles.size() - 2].getPosition().y);

                    //Sine to degrees
                    line.setRotation(-(asin(idk)  * 180 / 3.14));
                    if(circles[circles.size() - 1].getPosition().y < circles[circles.size() - 2].getPosition().y)
                    {
                        line.setRotation(180 - line.getRotation());
                    }

                    line.setPosition(circles[circles.size() - 2].getPosition().x, circles[circles.size() - 2].getPosition().y);
                    line.setFillColor(circles[circles.size() - 2].getFillColor());

                    lines.push_back(line);
                }
            }
        }
        window.clear(sf::Color::White);

        for(auto i : circles)
        {
            window.draw(i);
        }

        for(auto i : lines)
        {
            window.draw(i);
        }

        window.display();
    }
}
 

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #16 on: May 27, 2019, 12:49:51 pm »
I think pythagoreanTheorem should return a float instead of an int.

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #17 on: May 27, 2019, 01:22:39 pm »
Seems to have fixed the rigidness, but the skipping of dots is still present.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::CircleShape getPosition() returns big number
« Reply #18 on: May 27, 2019, 04:51:07 pm »
Maybe it's because of std::asin, which can only give results in [-pi/2, pi/2], therefore making other angles impossible to reach. std::atan2 is the only function that works correctly for the full range of angles, since it takes both X and Y coordinates. Read their documentation carefully, it's easy to miss something important.
Laurent Gomila - SFML developer

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #19 on: May 28, 2019, 03:00:37 am »
How do I use atan2? I am kinda confused how to find the angle at which to rotate.

Nvm. Figured out how to use it. Thanks for the advice! Let me know if there is anything I can improve performance wise.

Code:

#include <SFML/Graphics.hpp>
#include <cmath>
#include <iostream>

float pythagoreanTheorem(int a, int b)
{
    float c = sqrt((a * a) + (b * b));

    return c;
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(1920, 1080), "Drawing test");

    sf::Event event;
    sf::Color color = sf::Color::Blue;

    std::vector<sf::CircleShape> circles;
    std::vector<sf::RectangleShape> lines;

    sf::Vector2f mouseCoords = window.mapPixelToCoords(sf::Vector2i(sf::Mouse::getPosition(window))), oldMouseCoords = mouseCoords;

    while(window.isOpen())
    {
        mouseCoords = window.mapPixelToCoords(sf::Vector2i(sf::Mouse::getPosition(window)));

        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
            {
                window.close();
            }

            if(event.type == sf::Event::MouseMoved)
            {
                sf::CircleShape circle;
                circle.setRadius(5);
                circle.setPosition(mouseCoords);
                circle.setOrigin(circle.getRadius(), circle.getRadius());
                circle.setFillColor(color);

                circles.push_back(circle);

                if(circles.size() > 1)
                {
                    sf::RectangleShape line;

                    line.setSize(sf::Vector2f(pythagoreanTheorem(circles[circles.size() - 1].getPosition().x - circles[circles.size() - 2].getPosition().x, circles[circles.size() - 1].getPosition().y - circles[circles.size() - 2].getPosition().y), circles[circles.size() - 2].getRadius() * 2));
                    line.setOrigin(sf::Vector2f(0, line.getSize().y / 2));
                    line.setPosition(circles[circles.size() - 2].getPosition().x, circles[circles.size() - 2].getPosition().y);

                    //calculate arc-tangent
                    double idk = atan2(circles[circles.size() - 1].getPosition().y - circles[circles.size() - 2].getPosition().y, circles[circles.size() - 1].getPosition().x - circles[circles.size() - 2].getPosition().x);
                   
                    //convert radians to degrees and set them as the rotation
                    line.setRotation(idk  * 180 / 3.14);

                    line.setFillColor(circles[circles.size() - 2].getFillColor());

                    lines.push_back(line);
                }
            }

            if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter)
            {
                color = sf::Color::Red;
            }
        }
        window.clear(sf::Color::White);

        for(auto i : circles)
        {
            window.draw(i);
        }

        for(auto i : lines)
        {
            window.draw(i);
        }

        window.display();
    }
}
 
« Last Edit: May 28, 2019, 07:47:43 am by Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::CircleShape getPosition() returns big number
« Reply #20 on: May 28, 2019, 07:49:44 am »
Is it working as expected now?

Performance wise, the most obvious change would be to use a single vertex array rather than multiple circles and rectangles. But that requires some work ;)
Laurent Gomila - SFML developer

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #21 on: June 04, 2019, 05:30:12 pm »
Yes it is working as expected now, bust after intergrating into my painting program my performance concerns were assured. After a paint for a while, I notice that the whole program feels slower(mainly the dropdown menu speed changes). How would I go about making it into a single vertex array?

It is quite obvious that I am novice to all things programming, but I am learning so some advice would be very much appreciated.
« Last Edit: June 04, 2019, 05:32:03 pm by Xrey274 »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::CircleShape getPosition() returns big number
« Reply #22 on: June 04, 2019, 05:56:06 pm »
Rather than asking for the complete solution, I would suggest you have a look at the sf::VertexArray tutorial and the API documentation.

If things are still unclear after that, feel free to ask more concrete questions :)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::CircleShape getPosition() returns big number
« Reply #23 on: June 04, 2019, 07:17:33 pm »
Oh, I'd forgotten about this thread.

If I'm not mistaken, your intention is to have multiple thick straight lines with circular end points and circular corners?
You may want to give Selba Ward's Spline a try. Its most recent updates added these sorts of things :) so it's a single vertex array/draw call!
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything