c++ - 使用 SFML 绘制曲线会给出错误的形状
问题描述
我目前正在试验 SFML。我想使用数学曲线绘制复杂的形状。绘图仪中的方程式(我使用https://www.desmos.com/calculator)很好。绘图仪中的点列表(我使用http://www.shodor.org/interactivate/activities/SimplePlot/)很好。SFML 的结果显示不需要的伪影并且填充不正确(请参阅https://i50.servimg.com/u/f50/19/87/95/25/sfml11.png和https://i50.servimg.com/ u/f50/19/87/95/25/sfml12.png)。
我不知道为什么?是代码吗?显卡容量?我是否将 SFML 用于未设计的目的?坏juju?
任何帮助表示赞赏,
MC
g++ -std=c++11 ./k.cpp -o ./k -Wfatal-errors -lsfml-graphics -lsfml-window -lsfml-system
#include <iostream>
#include <random>
#include <string>
#include <math.h>
#include "SFML/Graphics.hpp"
using namespace std;
struct point
{
double x;
double y;
};
struct ellipse
{
int index;
point centerPoint;
double radiusX;
double radiusY;
sf::ConvexShape SFMLShape;
double xOffset;
double yOffset;
sf::Text ellipseTitle;
point textPosition;
};
ellipse computeCurve(point centerPoint,double radiusX,double radiusY,double beta)
{
// Based on https://www.mathcurve.com/courbes2d.gb/croixdemalte/croixdemalte.shtml
// This is a four parameters variant.
int numberOfPoints=400;
ellipse aCurve;
aCurve.SFMLShape.setPointCount(numberOfPoints);
aCurve.centerPoint.x=centerPoint.x;
aCurve.centerPoint.y=centerPoint.y;
aCurve.radiusX=radiusX;
aCurve.radiusY=radiusY;
double alpha=2*M_PI/numberOfPoints;
std::random_device randomDevice;
std::mt19937 seed(randomDevice());
float l=-2;
float p=-0.6;
float n=0.5;
float k=-0.5;
point point;
for(unsigned short i=0;i<=numberOfPoints/2;i++)
{
point.x=radiusX*cos(l*alpha*i)*(p+cos(n*alpha*i)/2 -k)+centerPoint.x;
point.y=radiusX*sin(alpha*i)*(p+cos(n*alpha*i)/2)+centerPoint.y;
aCurve.SFMLShape.setPoint(i,sf::Vector2f(point.x,point.y));
cout << "computeFish 1 point n°" << i << " " << point.x << " " << point.y << endl;
};
for(unsigned short i=0;i<=numberOfPoints/2;i++)
{
point.x=radiusX*cos(l*alpha*i)*(p+cos(n*alpha*i)/2 -k)+centerPoint.x;
point.y=-radiusX*sin(alpha*i)*(p+cos(n*alpha*i)/2)+centerPoint.y;
aCurve.SFMLShape.setPoint(numberOfPoints-i,sf::Vector2f(point.x,point.y));
cout << "computeFish 2 point n°" << numberOfPoints-i << " " << point.x << " " << point.y << endl;
};
aCurve.SFMLShape.setOrigin(aCurve.centerPoint.x,aCurve.centerPoint.y);
aCurve.SFMLShape.setPosition(aCurve.centerPoint.x,aCurve.centerPoint.y);
aCurve.textPosition.x=aCurve.centerPoint.x;
aCurve.textPosition.y=aCurve.centerPoint.y;
return aCurve;
}
int main()
{
const unsigned short windowWidth = 800;
const unsigned short windowHeight = 800;
sf::ContextSettings settings;
settings.antialiasingLevel = 4;
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "Demo",sf::Style::Default); // Default / None // Fullscreen
sf::Event myEvent;
sf::Clock ellipseClock;
bool stopped=false;
point centerPoint;
centerPoint.x=300;
centerPoint.y=300;
double radiusX=200;
double radiusY=150;
double beta=0;
ellipse mt=computeCurve(centerPoint,radiusX,radiusY,beta);
mt.SFMLShape.setOutlineColor(sf::Color::Red);
mt.SFMLShape.setFillColor(sf::Color(40,40,40,127));
mt.SFMLShape.setOutlineThickness(1.f);
while (window.isOpen())
{
while (window.pollEvent(myEvent))
{
if (myEvent.type == sf::Event::EventType::Closed)
{
window.close();
}
}
window.clear();
if (ellipseClock.getElapsedTime().asMilliseconds() > 100.0f)
{
//
ellipseClock.restart();
}
window.draw(mt.SFMLShape);
window.display();
}
return EXIT_SUCCESS;
}```
解决方案
您不能使用 绘制凹形sf::ConvexShape
。更确切地说:
虽然 的名字
sf::ConvexShape
暗示它应该只用于表示凸形,但它的要求要宽松一些。实际上,您的形状必须满足的唯一要求是,如果您继续从其重心到其所有点画线,则这些线必须以相同的顺序绘制。你不能“跳到前一行后面”。在内部,凸形是使用三角形扇形自动构造的,因此如果您的形状可以用三角形扇形表示,则可以使用sf::ConvexShape
. 通过这个轻松的定义,您可以使用sf::ConvexShape
例如绘制星星。
这个限制的一个解决方案是,您可以从多个凸形中制作凹形,但对于您的用例,它是不可行的。您唯一能做的就是绘制各个点(可能太多以至于看起来是连续的),但是对于这种工作,SFML 不适合。
推荐阅读
- c# - 使用 linq 按字符串 [] 分组/聚合
- javascript - 更改事件时的 iframe pdf 预览
- c# - 请求完成时通知 observable 完成
- blind - 如何在 Fiverr 中关闭盲模式?
- android - UI 未更新自定义对象列表的 MutableLiveData / ObservableField 属性随数据绑定而更改
- mlr3 - mlr3 中随机森林学习器的参数化
- c# - 用c#上传新图片时如何删除旧图片
- php - PHP Parse 错误:语法错误,意外的“新”(T_NEW),总是因为“=&”
- wordpress - Wordpress HTTPS 模式奇怪的行为
- html - 为 html 编辑器应用条件 css 样式表