SFML 自定义圆数学无法正常工作
SFML Custom Circle Math not working properly
我正在制作一个用sfml画圆的程序
使用等式
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;
}
现在,它的工作,但我有这个问题:
差距越来越大,我知道sfml会自动把floots四舍五入,但是我想用round函数。这个问题可以通过绘制四分之一圆两次来解决,从相反的坐标开始,但感觉不对,我想用这段代码作为数学原理的例子,如果没有其他办法,那么我想了解原因
谢谢大家的回答。
您遇到的问题是基于错误假设的天真实现的结果,即您可以使用 (x,y)
个点来绘制四分之一圆的近似值,这样每个点有不同的x
(或不同的y
)。
为了证明这个假设是错误的,让我们考虑半径 = 50,以及两个值 x1= 50
和 x2 = 49
。显然匹配y1 = 0
。 y2
呢?如果你像你一样使用天真的实现,你将计算
sqrt(50^2 - 49^2) = sqrt(99) ≈ 9.9
太天真了 y2 ≈ 9.9
或差不多 10
。但是 [1,9]
中 y
范围的 x
值是多少?答案是对于所有 y
,x
介于 49
和 50
之间。换句话说,x=49
和 x=50
确实需要至少 10 分,而不是两个。
您可以尝试使用一些 "draw line" 而不是 "draw point" 方法来解决这个问题,但最好使用一些众所周知的算法来绘制圆圈,例如 Midpoint circle algorithm或 Bresenham 的算法
我正在制作一个用sfml画圆的程序 使用等式
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;
}
现在,它的工作,但我有这个问题:
差距越来越大,我知道sfml会自动把floots四舍五入,但是我想用round函数。这个问题可以通过绘制四分之一圆两次来解决,从相反的坐标开始,但感觉不对,我想用这段代码作为数学原理的例子,如果没有其他办法,那么我想了解原因
谢谢大家的回答。
您遇到的问题是基于错误假设的天真实现的结果,即您可以使用 (x,y)
个点来绘制四分之一圆的近似值,这样每个点有不同的x
(或不同的y
)。
为了证明这个假设是错误的,让我们考虑半径 = 50,以及两个值 x1= 50
和 x2 = 49
。显然匹配y1 = 0
。 y2
呢?如果你像你一样使用天真的实现,你将计算
sqrt(50^2 - 49^2) = sqrt(99) ≈ 9.9
太天真了 y2 ≈ 9.9
或差不多 10
。但是 [1,9]
中 y
范围的 x
值是多少?答案是对于所有 y
,x
介于 49
和 50
之间。换句话说,x=49
和 x=50
确实需要至少 10 分,而不是两个。
您可以尝试使用一些 "draw line" 而不是 "draw point" 方法来解决这个问题,但最好使用一些众所周知的算法来绘制圆圈,例如 Midpoint circle algorithm或 Bresenham 的算法