Skip to content

Instantly share code, notes, and snippets.

@oprypin
Last active August 29, 2015 14:27
Show Gist options
  • Save oprypin/27ded2ee2bd8771b7a42 to your computer and use it in GitHub Desktop.
Save oprypin/27ded2ee2bd8771b7a42 to your computer and use it in GitHub Desktop.
SFML 2.3: gradual drawing of line shapes + erasing
#include <vector>
#include <cmath>
#include <SFML/Graphics.hpp>
#include "roundendedline.hpp"
int main() {
sf::Vector2f cross[][2] = {
{sf::Vector2f(0.1, 0.1), sf::Vector2f(0.9, 0.9)},
{sf::Vector2f(0.9, 0.1), sf::Vector2f(0.1, 0.9)}
};
size_t cross_size = sizeof(cross) / sizeof(cross[0]);
sf::ContextSettings cs(24, 0, 8);
sf::RenderWindow window(sf::VideoMode(300, 300), "SFML window", sf::Style::Default, cs);
window.setFramerateLimit(60);
auto scale = 300;
sf::RenderStates states;
states.transform.scale(scale, scale);
std::vector<CRoundendedLine> lines;
sf::VertexArray erase_va(sf::TrianglesStrip);
size_t line_index = 0;
size_t n;
size_t i = 0;
bool drawing = true;
bool erasing = false;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
if (drawing) {
if (line_index < cross_size) {
sf::Vector2f a = cross[line_index][0], b = cross[line_index][1];
if (i == 0) {
CRoundendedLine line;
line.setPosition(a);
line.setWidth(0.1);
line.setFillColor(sf::Color::Black);
lines.push_back(line);
float line_length = std::sqrt(std::pow(a.x - b.x, 2) + std::pow(a.y - b.y, 2));
n = line_length * 25;
}
float k = (float(i) / n);
lines.back().setEndPoint(sf::Vector2f(a * (1 - k) + b * k));
if (i == n) {
i = 0;
line_index += 1;
} else {
i += 1;
}
} else {
drawing = false;
erasing = true;
}
} else if (erasing) {
if (i == 0) {
n = 100;
erase_va.clear();
erase_va.append(sf::Vertex(sf::Vector2f(0.0, 0.0)));
}
int k = 10;
if (i % k == 0) {
int ii = i / k;
int nn = n / k;
if (ii < nn/2) {
float x = ii / float(nn/2 + (ii%2 ? 1 : -1));
float y = ii / float(nn/2 + (ii%2 ? -1 : 1));
erase_va.append(sf::Vertex(sf::Vector2f(x, 0.0), sf::Color::White));
erase_va.append(sf::Vertex(sf::Vector2f(0.0, y), sf::Color::White));
} else {
ii -= nn/2;
float x = ii / float(nn/2 + (ii%2 ? 1 : -1));
float y = ii / float(nn/2 + (ii%2 ? -1 : 1));
erase_va.append(sf::Vertex(sf::Vector2f(1.0, y), sf::Color::White));
erase_va.append(sf::Vertex(sf::Vector2f(x, 1.0), sf::Color::White));
}
}
i += 1;
if (i == n) {
i = 0;
lines.clear();
erase_va.clear();
erasing = false;
}
}
window.clear(sf::Color::White);
for (CRoundendedLine const& line: lines) {
window.draw(line, states);
}
if (erasing) {
window.draw(erase_va, states);
}
window.display();
}
}
#include "roundendedline.hpp"
CRoundendedLine::CRoundendedLine(const sf::Vector2f& endPoint, const float width)
: m_endPoint (endPoint), m_Width (width)
{
update();
}
void CRoundendedLine::setEndPoint(const sf::Vector2f& endPoint)
{
m_endPoint = endPoint;
update();
}
void CRoundendedLine::setWidth(const float width)
{
m_Width = width;
update();
}
size_t CRoundendedLine::getPointCount() const
{
return 30;
}
sf::Vector2f CRoundendedLine::getPoint(size_t index) const
{
sf::Vector2f P1(0.0, 0.0);
sf::Vector2f P2(m_endPoint - getPosition());
sf::Vector2f offset;
int iFlipDirection;
if(index < 15)
{
offset = P2;
iFlipDirection = 1;
}
else
{
offset = P1;
iFlipDirection = -1;
index -= 15;
}
float start = -atan2(P1.y - P2.y, P2.x - P1.x);
float angle = index * M_PI / 14 - M_PI / 2 + start;
float x = std::cos(angle) * m_Width / 2;
float y = std::sin(angle) * m_Width / 2;
return sf::Vector2f(offset.x + x * iFlipDirection, offset.y + y * iFlipDirection);
}
#ifndef ROUNDENDEDLINE_H
#define ROUNDENDEDLINE_H
// Class written by Foaly
// https://github.com/SFML/SFML/wiki/Source:-Round-Ended-Lines
#include <SFML/Graphics/Shape.hpp>
#include <cmath>
class CRoundendedLine : public sf::Shape
{
public:
CRoundendedLine(const sf::Vector2f& endPoint = sf::Vector2f(0, 0), const float width = 1.0);
void setEndPoint(const sf::Vector2f& endPoint);
void setWidth(const float width);
virtual size_t getPointCount() const;
virtual sf::Vector2f getPoint(size_t index) const;
private :
sf::Vector2f m_endPoint;
float m_Width;
};
#endif //ROUNDENDEDLINE_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment