Search code examples
c++mathsfml

SFML Custom Circle Math not working properly


Iam making a program to draw out circles with sfml using the equation

x^2+y^2=r^2 And then rounding

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

int main()
{
    unsigned int rad;
    unsigned int centerY;
    unsigned int centerX;
    std::cout << "Radius: ";
    std::cin >> rad;
    std::cout << "CenterX: ";
    std::cin >> centerX;
    std::cout << "CenterY: ";
    std::cin >> centerY;

    sf::RenderWindow window(sf::VideoMode(600,600), "Circle",sf::Style::Close);

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

        window.clear();
        sf::RectangleShape r(sf::Vector2f(1,1));
        r.setFillColor(sf::Color::White);
        //Calculate and draw right half
        for(int i = 0; i <= rad; i++)
        {
            int y = round(sqrt((rad*rad)-(i*i)));
            r.setPosition((float) centerX + i,(float) centerY + y);
            window.draw(r);
            r.setPosition((float) centerX + i,(float) centerY - y);
            window.draw(r);
        }
        //Calculate and draw left half
        for(int i = 0; i <= rad; i++)
        {
            int y = round(sqrt((rad*rad)-(i*i)));
            r.setPosition((float) centerX - y,(float) centerY + i);
            window.draw(r);
            r.setPosition((float) centerX - y,(float) centerY - i);
            window.draw(r);
        }
        window.display();
    }

    return 0;
}

Now, its working but i have this problem:enter image description here

There is a gap emerging and getting bigger and bigger, I know that sfml would automatically round the flaots, but i want to use the round function. And this issue can be Fixed by drawing the quarter circle twice, starting at opposing coordinates, but that doesnt feel right, i want to use this code as a example of the mathematic principle, and if there is no other way, then i would want to understand why

Thanks for all answers.


Solution

  • The problem you get is a result of a naive implementation that is based on a false assumption that you can draw a good approximation of a quarter of a circle using a number of (x,y) points such that every point has different x (or different y).

    To show that this assumption is wrong lets consider radius = 50, and two values x1= 50 and x2 = 49. Obviously the matching y1 = 0. What about y2? If you use naive implementation as you do, you will calculate

    sqrt(50^2 - 49^2) = sqrt(99) ≈ 9.9
    

    So naively y2 ≈ 9.9 or almost 10. Buts what is the x value for the range of ys in [1,9]? The answer is that for all those y, x lies somewhere between 49 and 50. In other words you really need at least 10 points for x=49 and x=50 rather than just two.

    You may try to work this around by using some "draw line" instead of a "draw point" method but it is better to use some well-known algorithm to draw circle such as Midpoint circle algorithm or Bresenham’s algrorithm