J'ai fini la méthode contains !
Je pense continuer à travailler sur les Boutons et autres pour SFML, c'était vraiment lucratif pour moi :)
Je pense faire un bouton Rectangle avec des coins arrondis maintenant :)
MODIFICATION : Après réfléxion, ce code marche très bien pour faire de beau rond mais pas pour de beaux ovales, car les extrémités de sont pas bien arrondies dans le cas de diamètre trop différent...
Je suis désolé, je ne maitrise pas encore les équations de la forme : x=a(Y-K)^2+H, ducoup je mettrais à jour ce code plus tard, j'ai déjà l'idée de comment le traiter (en fonction du diamètre le plus long).
MAIS, le plus important est que les ronds marchent bien, car ils me serviront pour le RoundRect qui sera plus utile que des Ovales :)
Enfin bref, voilà quand même le code :)
Ovale.hpp
#ifndef SFML_OVALE_HPP
#define SFML_OVALE_HPP
#include <SFML/System/Vector2.hpp>
namespace sf
{
template <typename T>
class Ovale
{
public :
Ovale();
Ovale(T leftX, T topY, T diamX, T diamY);
Ovale(const Vector2<T>& position, const Vector2<T>& size);
bool contains(T x, T y) const;
bool contains(const Vector2<T>& point) const;
T left;
T top;
T diameterX;
T diameterY;
};
#include <SFML/Graphics/Ovale.inl>
typedef Ovale<int> IntOvale;
typedef Ovale<float> FloatOvale;
} // namespace sf
#endif // SFML_OVALE_HPP
Ovale.inl
////////////////////////////////////////////////////////////
template <typename T>
Ovale<T>::Ovale() :
left(0),
top(0),
diameterX(0),
diameterY(0)
{
}
////////////////////////////////////////////////////////////
template <typename T>
Ovale<T>::Ovale(T leftX, T topY, T diamX, T diamY) :
left(leftX),
top(topY),
diameterX(diamX),
diameterY(diamY)
{
}
////////////////////////////////////////////////////////////
template <typename T>
Ovale<T>::Ovale(const Vector2<T>& position, const Vector2<T>& size) :
left(positon.x),
top(position.y),
diameterX(size.x),
diameterY(size.y)
{
}
////////////////////////////////////////////////////////////
template <typename T>
bool Ovale<T>::contains(T x, T y) const
{
float yTest;
float a;
float b;
float c;
float Beta(top);
float Alpha(left+diameterX/2);
float x1(left);
float x2(left+diameterX);
if (y = top+diameterY/2)
{
if (x >= x1 && x <= x2) return true;
else return false;
}
else if (y > top+diameterY/2)
{
Beta += diameterY;
a = -Beta/(x1-Alpha)^2;
b = -a*x1 -a*x2;
c = x1*x2*a;
yTest = a*x^2 + b*x + c;
if (yTest >= y && x >= x1 && x <= x2) return true;
else return false;
}
else if (y < top+diameterY/2)
{
a = -Beta/(x1-Alpha)^2;
b = -a*x1 -a*x2;
c = x1*x2*a;
yTest = a*x^2 + b*x + c;
if (yTest <= y && x >= x1 && x <= x2) return true;
else return false;
}
}
////////////////////////////////////////////////////////////
template <typename T>
bool Ovale<T>::contains(const Vector2<T>& point) const
{
return contains(point.x, point.y);
}
Bonjour,
Tout d'abord, remarque bien qu'en C++, l'opérateur ^ ne calcule pas une puissance mais c'est l'opérateur ou exclusif bit à bit.
Ensuite, je voudrais pas te dégouter mais tu peux beaucoup simplifier ta fonction.
D'après l'équation cartésienne d'une ellipse (cf wikipédia (http://fr.wikipedia.org/wiki/Ellipse_%28math%C3%A9matiques%29#.C3.89quation_cart.C3.A9sienne)), on peut procéder comme ceci:
template <typename T>
bool Ovale<T>::contains(T x, T y) const
{
// calcul des rayons de l'ellipse
T a = diameterX / 2;
T b = diameterY / 2;
// expression de x et y par rapport au centre de l'ellipse
x -= left + a;
y -= top + b;
// x² / a² + y² / b² = 1 lorsque un point est situé sur l'ellipse
// ici, l'opérateur <= permet de savoir si le point est situé dans l'ellipse
return (x*x) / (a*a) + (y*y) / (b*b) <= 1;
}
Ducoup, je peux juste rajouter mes fichiers dans les sources que j'ai téléchargé et ensuite en compilant SFML avec CMake j'aurais ma classe ?
Ou il y a d'autres choses à faire avant ?
Comme c'est une classe template définie dans des headers, il n'y a pas besoin de compiler.
Si tu veux faire un truc propre, tu peux ajouter le nom des fichiers dans le CMakeLists du module graphique (https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/CMakeLists.txt).
Merci, le fait de m'aider ne me dégoute pas du tout, si je poste le but c'est justement de pouvoir être amélioré au maximum.
Je suis encore en première S donc j'ai pas encore fini de voir tout ce qui est fonction du genre Polynôme.
En attendant, voilà ma classe RoundRect ! (elle, elle marche correctement !)
RoundRect.hpp
#ifndef SFML_ROUNDRECT_HPP
#define SFML_ROUNDRECT_HPP
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/Ovale.hpp> //je mets ca même si c'est pas le vrai chemin :)
namespace sf
{
template <typename T>
class RoundRect : public Ovale, public Rect
{
public :
RoundRect();
RoundRect(T leftX, T topY, T diamX, T diamY, T rad = 0);
RoundRect(const Vector2<T>& position, const Vector2<T>& size, T rad = 0);
bool contains(T x, T y) const;
bool contains(const Vector2<T>& point) const;
T left;
T top;
T width;
T height;
T radius;
};
#include <SFML/Graphics/Ovale.inl>
typedef RoundRect<int> IntRoundRect;
typedef RoundRect<float> FloatRoundRect;
} // namespace sf
#endif // SFML_ROUNDRECT_HPP
RoundRect.inl
////////////////////////////////////////////////////////////
template <typename T>
RoundRect<T>::RoundRect() :
left(0),
top(0),
width(0),
height(0),
radius(0)
{
}
////////////////////////////////////////////////////////////
template <typename T>
RoundRect<T>::RoundRect(T leftX, T topY, T diamX, T diamY, T rad) :
left(leftX),
top(topY),
width(diamX),
height(diamY),
radius(rad)
{
}
////////////////////////////////////////////////////////////
template <typename T>
RoundRect<T>::RoundRect(const Vector2<T>& position, const Vector2<T>& size, T rad) :
left(position.x),
top(position.y),
width(size.x),
height(size.y),
radius(rad)
{
}
////////////////////////////////////////////////////////////
template <typename T>
bool RoundRect<T>::contains(T x, T y) const
{
Ovale<T> leftTop(left,top,radius,radius);
Ovale<T> leftBottom(left,top+height-radius*2,radius,radius);
Ovale<T> rightTop(left+width-radius*2,top,radius,radius);
Ovale<T> rightBottom(left+width-radius*2,top+height-radius*2,radius,radius);
Rect<T> bloc1(left+radius,top,width-radius*2,height);
Rect<T> bloc2(left,top+radius,width,height-radius*2);
if(leftTop.contains(x,y)==true || leftBottom.contains(x,y)==true || rightTop.contains(x,y)==true || rightBottom.contains(x,y)==true || bloc1.contains(x,y)==true || bloc2.contains(x,y)==true)
{
return true;
}
else return false;
}
////////////////////////////////////////////////////////////
template <typename T>
bool RoundRect<T>::contains(const Vector2<T>& point) const
{
return contains(point.x, point.y);
}