Hi there,
I'm trying to implement a class that draws round ended lines. For that I made a class that inherits from sf::Shape. First I thought I implement a class that draws lines. I did that and i works. But now I'm not sure how to put the rounded ends on it. I'm thinking that I have to compute half a circle and just put it on the two end points, but I'm not quiet sure how to compute the "rotation" of the circle. Can somebody point me in the right direction?
Here is my code so far.
Header File:
#ifndef ROUNDENDEDLINE_H
#define ROUNDENDEDLINE_H
#include <SFML/Graphics/Shape.hpp>
#include <cmath>
#include <iostream>
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 unsigned int getPointCount() const;
virtual sf::Vector2f getPoint(unsigned int index) const;
private :
sf::Vector2f m_endPoint;
float m_Width;
};
#endif //ROUNDENDEDLINE_H
Implementation:
#include "RoundendedLine.h"
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();
}
unsigned int CRoundendedLine::getPointCount() const
{
return 4;
}
// Compute the normal of a segment
sf::Vector2f computeNormal(const sf::Vector2f& p1, const sf::Vector2f& p2)
{
sf::Vector2f normal(p1.y - p2.y, p2.x - p1.x);
float length = std::sqrt(normal.x * normal.x + normal.y * normal.y);
if (length != 0.f)
normal /= length;
return normal;
}
sf::Vector2f CRoundendedLine::getPoint(unsigned int index) const
{
sf::Vector2f P1(1.0, 0.0);
sf::Vector2f P2(m_endPoint + sf::Vector2f(1.0, 0.0) - getPosition());
// Compute the extrusion direction
sf::Vector2f Normal = computeNormal(P1, P2);
Normal *= m_Width / 2;
switch (index)
{
default:
case 0: return sf::Vector2f(P1 - Normal);
case 1: return sf::Vector2f(P2 - Normal);
case 2: return sf::Vector2f(P2 + Normal);
case 3: return sf::Vector2f(P1 + Normal);
}
}
Usage:
#include <SFML/Graphics.hpp>
#include "RoundendedLine.h"
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");
CRoundendedLine RoundendedLine;
RoundendedLine.setPosition(200,200);
RoundendedLine.setEndPoint(sf::Vector2f(270, 300));
RoundendedLine.setWidth(11);
sf::Vertex* startVertex = new sf::Vertex(sf::Vector2f(200, 200), sf::Color::Red);
sf::Vertex* endVertex = new sf::Vertex(sf::Vector2f(270, 300), sf::Color::Blue);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
// Close Event
if (event.type == sf::Event::Closed)
window.close();
// Escape key pressed
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
window.close();
}
window.clear();
window.draw(RoundendedLine);
window.draw(startVertex, 1, sf::Points);
window.draw(endVertex, 1, sf::Points);
window.display();
}
return 0;
}