begin process at 2012 05 27 15:02:48
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > COURBE DE BÉZIER

COURBE DE BÉZIER


 Description

Cliquez pour voir la capture en taille normale
Cette petite source permet de gérer des courbes de Bézier avec autant de points de contrôle que l'on veut.
Il s'agit en fait d'approximations de courbes, car elles sont constituées de segments dont on peut spécifier le nombre (précision).
La classe de base (Bezier) permet, à partir d'une liste de coordonnées de points de contrôle et d'une précision, de renvoyer les différents points de la courbe. On peut donc ensuite dessiner la courbe (ce qui est fait avec l'exemple "GUI").
Les deux exemples fournis prennent en argument des fichiers de points de contrôle, il y en a déjà quatre qui sont écrits.
L'algorithme utilisé semble raisonnablement rapide bien qu'il soit peut-être possible de faire mieux (on utilise le calcul de barycentres).

Le code est commenté et documenté (la documentation est déjà générée et le fichier Doxyfile est fourni).



Attention, le zip et le code fournis sur cette page ne sont pas forcément à jour ! Pour voir les dernières sources, rendez-vous ici : https://bitbucket.org/mcc/dev/src/tip/Bezier/

Source

  • /**
  • * \file Bezier.cpp
  • * \brief Définition de la classe Bezier.
  • */
  • #include "Bezier.hpp"
  • Bezier::Bezier() : m_precision(15), m_autoUpdate(true) {
  • }
  • Bezier::Bezier(int precision) : m_precision(precision), m_autoUpdate(true) {
  • }
  • Bezier::Bezier(int precision, bool autoUpdate) : m_precision(precision),
  • m_autoUpdate(autoUpdate) {
  • }
  • Bezier::Bezier(std::string filename) {
  • double x, y;
  • m_autoUpdate = false;
  • m_precision = 15;
  • std::ifstream f(filename.c_str());
  • if(f.is_open()) {
  • f >> m_precision;
  • while(f >> x >> y) {
  • addControlPoint(x, y);
  • }
  • f.close();
  • }
  • update();
  • }
  • void Bezier::addControlPoint(const BezierPoint& pt) {
  • m_controlPoints.push_back(pt);
  • updateBounds();
  • if(m_autoUpdate) update();
  • }
  • void Bezier::addControlPoint(double x, double y) {
  • addControlPoint(BezierPoint(x, y));
  • }
  • void Bezier::removeControlPoint(const BezierPoint& pt) {
  • std::vector<BezierPoint>::iterator it;
  • it = std::find(m_controlPoints.begin(), m_controlPoints.end(), pt);
  • if(it != m_controlPoints.end()) {
  • m_controlPoints.erase(it);
  • }
  • updateBounds();
  • if(m_autoUpdate) update();
  • }
  • void Bezier::removeControlPoint(double x, double y) {
  • removeControlPoint(BezierPoint(x, y));
  • }
  • BezierPoint Bezier::deCasteljau(const std::vector<BezierPoint>& pts,
  • double pos) {
  • if(pts.size() == 1) return pts[0];
  • std::vector<BezierPoint> pts2;
  • for(unsigned int i = 0; i < pts.size() - 1; i++) {
  • BezierPoint p1(pts[i].x(), pts[i].y(), 1 - pos);
  • BezierPoint p2(pts[i + 1].x(), pts[i + 1].y(), pos);
  • pts2.push_back(p1.barycentre(p2));
  • }
  • return deCasteljau(pts2, pos);
  • }
  • void Bezier::update() {
  • if(isValid()) {
  • m_curvePoints.clear();
  • for(int i = 0; i <= m_precision; i++) {
  • double pos = i / (double)m_precision;
  • m_curvePoints.push_back(deCasteljau(m_controlPoints, pos));
  • }
  • }
  • }
  • const std::vector<BezierPoint>& Bezier::curvePoints() {
  • return m_curvePoints;
  • }
  • const std::vector<BezierPoint>& Bezier::controlPoints() {
  • return m_controlPoints;
  • }
  • void Bezier::setPrecision(int precision) {
  • m_precision = precision;
  • if(m_autoUpdate) update();
  • }
  • int Bezier::precision() {
  • return m_precision;
  • }
  • void Bezier::setAutoUpdate(bool autoUpdate) {
  • m_autoUpdate = autoUpdate;
  • }
  • bool Bezier::autoUpdate() {
  • return m_autoUpdate;
  • }
  • Bezier::BezierBounds Bezier::bounds() const {
  • return m_bounds;
  • }
  • void Bezier::updateBounds() {
  • double minX = m_controlPoints[0].x();
  • double minY = m_controlPoints[0].y();
  • double maxX = m_controlPoints[0].x();
  • double maxY = m_controlPoints[0].y();
  • for(unsigned int i = 0; i < m_controlPoints.size(); i++) {
  • if(m_controlPoints[i].x() < minX) {
  • minX = m_controlPoints[i].x();
  • }
  • if(m_controlPoints[i].x() > maxX) {
  • maxX = m_controlPoints[i].x();
  • }
  • if(m_controlPoints[i].y() < minY) {
  • minY = m_controlPoints[i].y();
  • }
  • if(m_controlPoints[i].y() > maxY) {
  • maxY = m_controlPoints[i].y();
  • }
  • }
  • m_bounds.tl.setX(minX);
  • m_bounds.tl.setY(minY);
  • m_bounds.br.setX(maxX);
  • m_bounds.br.setY(maxY);
  • }
  • bool Bezier::isValid() {
  • return m_precision > 0 && m_controlPoints.size() > 2;
  • }
/**
 * \file Bezier.cpp
 * \brief Définition de la classe Bezier.
 */

#include "Bezier.hpp"	

Bezier::Bezier() : m_precision(15), m_autoUpdate(true) {
}

Bezier::Bezier(int precision) : m_precision(precision), m_autoUpdate(true) {
}

Bezier::Bezier(int precision, bool autoUpdate) : m_precision(precision),
												 m_autoUpdate(autoUpdate) {
}

Bezier::Bezier(std::string filename) {
	double x, y;
	m_autoUpdate = false;
	m_precision = 15;
	
	std::ifstream f(filename.c_str());
	if(f.is_open()) {
		f >> m_precision;
		while(f >> x >> y) {
			addControlPoint(x, y);
		}
		f.close();
	}
	
	update();
}

void Bezier::addControlPoint(const BezierPoint& pt) {
	m_controlPoints.push_back(pt);
	updateBounds();
	if(m_autoUpdate) update();
}

void Bezier::addControlPoint(double x, double y) {
	addControlPoint(BezierPoint(x, y));
}

void Bezier::removeControlPoint(const BezierPoint& pt) {
	std::vector<BezierPoint>::iterator it;
	it = std::find(m_controlPoints.begin(), m_controlPoints.end(), pt);
	if(it != m_controlPoints.end()) {
		m_controlPoints.erase(it);
	}
	updateBounds();
	if(m_autoUpdate) update();
}

void Bezier::removeControlPoint(double x, double y) {
	removeControlPoint(BezierPoint(x, y));
}

BezierPoint Bezier::deCasteljau(const std::vector<BezierPoint>& pts,
								double pos) {
	if(pts.size() == 1) return pts[0];
	std::vector<BezierPoint> pts2;
	for(unsigned int i = 0; i < pts.size() - 1; i++) {
		BezierPoint p1(pts[i].x(), pts[i].y(), 1 - pos);
		BezierPoint p2(pts[i + 1].x(), pts[i + 1].y(), pos);
		pts2.push_back(p1.barycentre(p2));
	}
	return deCasteljau(pts2, pos);
}

void Bezier::update() {
	if(isValid()) {
		m_curvePoints.clear();
		for(int i = 0; i <= m_precision; i++) {
			double pos = i / (double)m_precision;
			m_curvePoints.push_back(deCasteljau(m_controlPoints, pos));
		}
	}
}

const std::vector<BezierPoint>& Bezier::curvePoints() {
	return m_curvePoints;
}

const std::vector<BezierPoint>& Bezier::controlPoints() {
	return m_controlPoints;
}
		
void Bezier::setPrecision(int precision) {
	m_precision = precision;
	if(m_autoUpdate) update();
}
		
int Bezier::precision() {
	return m_precision;
}

void Bezier::setAutoUpdate(bool autoUpdate) {
	m_autoUpdate = autoUpdate;
}

bool Bezier::autoUpdate() {
	return m_autoUpdate;
}

Bezier::BezierBounds Bezier::bounds() const {
	return m_bounds;
}

void Bezier::updateBounds() {
	double minX = m_controlPoints[0].x();
	double minY = m_controlPoints[0].y();
	double maxX = m_controlPoints[0].x();
	double maxY = m_controlPoints[0].y();
	
	for(unsigned int i = 0; i < m_controlPoints.size(); i++) {
		if(m_controlPoints[i].x() < minX) {
			minX = m_controlPoints[i].x();
		}
		if(m_controlPoints[i].x() > maxX) {
			maxX = m_controlPoints[i].x();
		}
		if(m_controlPoints[i].y() < minY) {
			minY = m_controlPoints[i].y();
		}
		if(m_controlPoints[i].y() > maxY) {
			maxY = m_controlPoints[i].y();
		}
	}
	
	m_bounds.tl.setX(minX);
	m_bounds.tl.setY(minY);
	m_bounds.br.setX(maxX);
	m_bounds.br.setY(maxY);
}

bool Bezier::isValid() {
	return m_precision > 0 && m_controlPoints.size() > 2;
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture ÉVALUATEUR D'EXPRESSIONS BOOLÉENNES (BEE)
Source avec Zip Source avec une capture SYSTÈME D'ANNULER-REFAIRE PAR ARBRE (TURS)

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture COURBES NURBS 3D DANS OPENSCENEGRAPH par ordiman85
Source avec Zip Source avec une capture REPRESENTATION GRAPHIQUE DE DONNEES par wildhawk
Source avec Zip Source avec une capture CLASSE CGRAPHXY par bobbyantho
Source avec Zip Source avec une capture Source .NET (Dotnet) COURBE DE BÉZIER EN TROIS POINTS (CONSTRUCTIONS BARYCENTRIQU... par florian15
Source avec Zip Source avec une capture PICKING OPENGL(GLUT) / INTERPOLATION BÉZIER,B-SPLINE,CATMULR... par luhtor

Commentaires et avis

Aucun commentaire pour le moment.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Problème avec le copier coller [ par Unknown ] J'ai un projet où j'utilise un composant image. Il me permet l'affichage d'une courbe a partir d'un oscilloscope numérique. Mon problème est que je do faire une courbe toute conne [ par Axool ] pouvez-vous m'aider svp: j'aimerais savoir faire une courbe toute conne, vraiment le + simple possible...mercips: si au passage vous savez comment cré desiner une courbe a partir des valeurs d'un tableau [ par aymentri ] je veut afficher un graphe en utilisant des valeurs stokées dans un tableau Sismographe [ par nahs ] Bonjours,Je cherche un moyen de tracer une courbe de la meme fason qu'un sismographe c'est à dire: sur une fenetre on verrai la feuille qui bouge de d courbe C++ [ par tguinel ] salut,je veut afficher un graphe en utilisant des valeurs stokées dans une base données(en C++, visualC++ 6.0).merci de m'aider. Rafraichissement [ par gus2647 ] Bonjour,J utilise VC++ 6 et les MFC. lorsque je trace une courbe, elle s affiche correctement, mais lorsque je cree par dessus par exemple une CListCt Comment faire un Defilemant de courbe en API [ par nahs ] Bonjours,J'aurai voulu saloire comment faire un effet defilent en API; les instructions qui permet de faire cela.Merci utilisation du Tchart??(builder) [ par kach23 ] bonjour,je fais une acquisition de mesure(carte NI) avec builder 6. en utilisant le timer de builder je pe realiser une courbe (Tchart) qui evolue au Line To rapide [ par BarthOlivier ] Salut,Je fait plusieurs occurence de MoveTo + LineTo sur un CDC.Est-il possible d'optimiser LineTo avec une autre fonction ?J'avais essayé en passant tracer courbe en excel à partir de MFC [ par mabrouka ] bonjour,comment tracer une courbe en excel à partir de visual c++ MFCmerci


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,983 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales