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

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

0 Members and 1 Guest are viewing this topic.

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
sf::CircleShape getPosition() returns big number
« on: March 31, 2019, 09:17:48 pm »
I've been messing around with interpolation and I've almost reached something that I could call usable and then bam big problem. I first experimented by just interpolating between 2 static points and now I added lines that are draw when the mouse moves. The probem is after a couple of seconds the whole thing crashes and I see that .getPosition() returns numbers with 6 or more digits.

Here's the code:
#include <SFML/Graphics.hpp>
#include <iostream>

int setMaxValue(sf::CircleShape circle, bool& y)
{
    int a = 0;

    if(circle.getPosition().y > circle.getPosition().x)
    {
        a = circle.getPosition().y;
        y = true;
    }
    else
        a = circle.getPosition().x;

    return a;
}

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

    sf::Event event;

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

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

    bool ended = false, isY = false;
    int maxValue0, maxValue1, maxValue2;

    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 newCircle;

                newCircle.setRadius(50);
                newCircle.setOrigin(newCircle.getRadius(), newCircle.getRadius());
                newCircle.setPosition(mouseCoords);
                newCircle.setFillColor(sf::Color::Red);

                circles.push_back(newCircle);

                ended = false;
            }
        }

        if(ended == false && circles.size() > 1)
        {
            maxValue0 = setMaxValue(circles[circles.size() - 2], isY);
            maxValue1 = setMaxValue(circles[circles.size() - 1], isY);

            if(maxValue0 > maxValue1)
                maxValue2 = maxValue0 - maxValue1;
            else
                maxValue2 = maxValue1 - maxValue0;

                std::cout<<circles.size()<<std::endl;
                std::cout<<circles[circles.size() - 2].getPosition().x<<" "<<circles[circles.size() - 2].getPosition().y<<std::endl;

            for(int i = 0; i < maxValue2; ++i)
            {
                sf::CircleShape newCircle;

                int x, y;

                if(isY == true)
                {
                    y = circles[circles.size() - 2].getPosition().y + i;
                    x = (((y - circles[circles.size() - 2].getPosition().y) * (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].getPosition().x;
                }
                else
                {
                    x = circles[circles.size() - 2].getPosition().x + i;
                    y = (((x - circles[circles.size() - 1].getPosition().x) * (circles[circles.size() - 1].getPosition().y - circles[circles.size() - 2].getPosition().y)) / (circles[circles.size() - 1].getPosition().x - circles[circles.size() - 2].getPosition().x)) + circles[circles.size() - 2].getPosition().y;
                }

                sf::Vector2f finalPos(x, y);

                newCircle.setRadius(50);
                newCircle.setOrigin(newCircle.getRadius(), newCircle.getRadius());
                newCircle.setPosition(finalPos);
                newCircle.setFillColor(sf::Color::Red);

                circles.push_back(newCircle);

                if(i == maxValue2 - 1)
                {
                    ended = true;
                }
            }
        }

        window.clear(sf::Color::White);

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

        window.display();
    }
}
 

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #1 on: March 31, 2019, 09:34:05 pm »
From what I can see the problem seems to arrises from "circles[circles.size() -2].getPosition" no idea why that would cause it tho. -1 seems to have no problem

fallahn

  • Sr. Member
  • ****
  • Posts: 492
  • Buns.
    • View Profile
    • Trederia
Re: sf::CircleShape getPosition() returns big number
« Reply #2 on: April 02, 2019, 07:22:59 pm »
If circles.size() is ever 0 or 1 then subtracting 2 from it is going to cause the value to wrap around (size_t is an unsigned value) and you'll index your vector with a very large number. This means you'll be effectively trying to read some random memory which is most likely why the position has an apparently odd value stored in it.

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #3 on: April 03, 2019, 05:21:22 am »
That's not the problem - made the if accept the vector only if it was bigger than 2 and manually logged the circles.size() and circles.size() - 2. Program still crashed with bad_alloc exception. Also the .getPosition() still returns crazy numbers.

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::CircleShape getPosition() returns big number
« Reply #4 on: April 03, 2019, 10:29:58 am »
By "big" numbers, do you you mean large in value or many digits? It's unclear from your original description.
An example of the sorts of "crazy" numbers you are getting might help narrow down the cause.

Are you creating circles for every co-ordinate (usually pixel) between each point?
Are you also adding a circle to the vector every time the mouse moves? That's a pretty large vector. It should also be reserved in advance to avoid it moving around when increasing inside.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #5 on: April 03, 2019, 06:36:04 pm »
Yes, I am creating a circle per pixel. Also I probably should reserve it.

This is the kind of crazy numbers I am talking about: https://imgur.com/a/YDWXywq

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::CircleShape getPosition() returns big number
« Reply #6 on: April 06, 2019, 09:01:17 pm »
Okay, well, I've tested your code.
Your "control circles" work fine if you remove the "if (ended == false..." section so it's clear that the interpolation is the problem.
Also, do you realise how quickly the circle vector gets to tens of thousands when interpolating?

Quick question, why are interpolating with so many circles? Can you not draw a thick line between each pair of circles?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #7 on: April 07, 2019, 12:03:11 am »
I am not adding thick lines between them as this is supposed to be a thick line. I'm not really satisfied with Selba Ward's Spline so I decided to try to make something myself. Using sf::TriangleStrip would be an option to fill in, but I have no idea how to do that.

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::CircleShape getPosition() returns big number
« Reply #8 on: April 07, 2019, 09:59:11 pm »
A thick line is simply a rectangle (or a quad or two triangles). Whether you use Selba Ward's Line class (thick line), sf::RectangleShape or a manual vertex array (quad/2 triangles), you can just draw that between each control circle.

I presume that your intention is a thick, poly-line with curved corners and a semi-circle added to each end of the poly-line?

May I ask what with Selba Ward's Spline you weren't satisfied with? Is it just missing the curved corners on non-Bezier poly-lines?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #9 on: April 08, 2019, 11:06:54 am »
Selba Ward has a great concept with Splines, but I really wished it had curved(rounded) corners, also the bigger problem was that while drawing I could see the triangle realine and move. It almost looked like little artifacts that were sticking out slightly from the line it self.

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::CircleShape getPosition() returns big number
« Reply #10 on: April 08, 2019, 04:08:05 pm »
You should be able to control Selba Ward's Spline to do what you need by adding in extra points. Basically, for each corner, add in a couple of control points at the same position with handles to create the curve. Look up Bezier curves for more information.

That said, if you still want to do it yourself, you could make a thick line between each point and the also draw a circle over each of those points. You can use the above mentioned methods for easily creating a thick line.



I'd like to see what sort of artifacts you are describing. Can you screenshot or video capture them. Since this is slightly off-topic for this thread, you can discuss it on this one and I'll see what I can do:
https://en.sfml-dev.org/forums/index.php?topic=19496.0

Also, feel free to raise an issue on GitHub about the problem. Note, however, that curved corners has already been discussed within the issues.
https://github.com/Hapaxia/SelbaWard/issues
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #11 on: April 30, 2019, 12:51:20 am »
I am having trouble figuring out how to calculate how many degrees to rotate the rectangle to connect the dots

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Xrey274

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: sf::CircleShape getPosition() returns big number
« Reply #13 on: May 05, 2019, 07:57:33 pm »
Yep. Dunno if its the best way, but sin-1 seems to work well.

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::CircleShape getPosition() returns big number
« Reply #14 on: May 05, 2019, 10:29:23 pm »
You're probably going to want to use this:
https://en.cppreference.com/w/cpp/numeric/math/atan2
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*