Lissage d'une courbe définit par des points (subdivision)

Soyez le premier à donner votre avis sur cette source.

Vue 20 505 fois - Téléchargée 1 255 fois

Description

Petite mise a jour la formule est modifiée, car elle présentait une petite anomalie!
  • Controle externe de la tension
  • Contrôle externe du nombre d'étapes de subdivision
  • Boucler la courbe, en gros faire des cercles déformés, c'est a dire de ne pas avoir une courbe avec 2 extrémités mais une boucle fermée
  • Bouger les points de contrôles et déformer en direct la courbe
  • Affichage des lignes de contrôle
  • Affichage des vertices


Pour ajouter un point :: Appuyer sur shift et kliker sur le PictureBox
Pour sélectionner un point :: Klik droit vers le point de contrôle
Pour bouger un point :: Il faut ke le point soi sélectionner :p, puis kliker sur le PictureBox

Au début je cherchait un algorithme pour lisser des objets 3D
Je l'ai trouvé! Je me suis dit que cela pouvait avoir une utilité
pour lisser une courbe 2D.

Le principe est simple, on définit une courbe en placant quelques points
Et on lance l'algorithme de subdivision, généralement 3 subdivision suffisent pour avoir une courbe suffisement lisse.

Si vous voulez voir à quoi cela ressemble :: Capture décran

Le code est très simple, d'ailleurs le voila :

Source / Exemple :


Private Type PointsV
    X As Integer
    Y As Integer
End Type

Dim NmbPoint As Integer

Dim I As Integer

Dim Points() As PointsV

Sub DrawCourbe()
On Error Resume Next
'---Affiche la courbe
Pic.Cls
For I = 0 To NmbPoint - 1
    '---Affiche le point rouge
    Pic.DrawWidth = 5
    Pic.ForeColor = vbRed
    Pic.PSet (Points(I).X, Points(I).Y)
    '---Affiche la ligne
    Pic.DrawWidth = 1
    Pic.ForeColor = vbWhite
    Pic.Line (Points(I).X, Points(I).Y)-(Points(I + 1).X, Points(I + 1).Y)
Next
End Sub

Sub Subdivise()
On Error Resume Next
'---Calcul la nouvelle courbe
Dim W As Single
'---W est le facteur de tension appartenant à l'interval [0,1]
'   plus W est proche de 0, plus la courbe finale ressemblera à la courbe originelle
'   plus W est proche de 1, plus la courbe finale sera rectiligne

W = 0.5
'---Redimensionne la structure de la grille pour stocker les nouveaux points
ReDim Preserve Points(2 * NmbPoint - 1)
For I = NmbPoint-1 To 0 Step -1
'---Replace les points deja présents dans la nouvelle structure
    Points(2 * I) = Points(I)
'---Créé les nouveaux points par interpolation, le nouveau point se trouve
'   au milieu du segment délimité par le point (I)=(2 * I) et le point (I - 1)
    Points(2 * I - 1).X = Int((Points(I).X + Points(I - 1).X) / 2)
    Points(2 * I - 1).Y = Int((Points(I).Y + Points(I - 1).Y) / 2)
'---Déplace les points deja présents
    Points(2 * I).X = Points(2 * I).X * (1 - W) + W / 2 * (Points(2 * I - 1).X + Points(2 * I + 1).X)
    Points(2 * I).Y = Points(2 * I).Y * (1 - W) + W / 2 * (Points(2 * I - 1).Y + Points(2 * I + 1).Y)
Next
NmbPoint = UBound(Points) + 1
DrawCourbe
End Sub

Private Sub Command1_Click()
    Subdivise
End Sub

Private Sub Pic_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
'---Click pour créer un point
    ReDim Preserve Points(NmbPoint)
    Points(NmbPoint).X = X
    Points(NmbPoint).Y = Y
    NmbPoint = NmbPoint + 1
    DrawCourbe
End Sub

Conclusion :


Ce code ne présente pas la même chose que dans le Zip, ici, c'est juste pour une courbe à 2 extrémités, dans le Zip il y'a le code pour la boucle.
Le Zip est également présent!

La source de lissage d'un objet 3D est disponible ici :

http://www.vbfrance.com/article.aspx?Val=9684
si vous voulez un avant gout niveau graphisme voila 2 captures :
http://geffd.free.fr/Coding/Sub3D1.jpg
http://geffd.free.fr/Coding/Sub3D2.jpg

Il existe de nombreux principes de subdivision, Catmull-Clarck, Peter, Loop, Butterfly, Butterfly modifiée, on trouve quelques docs très théoriques (mathématiques) en anglais sur le net, si vous êtes curieux, il ne tient qu'a vous de poser une petite question a Monsieur Google :)

Mon algorithme est très simple et n'offre pas la même précision de lissage que les méthodes dont j'ai donné le nom surtout pour les surfaces 3D, mais il a le mérite d'etre très court et facilement compréhensible!

Si les subdivisions vous intéressent voici deux liens:

www.subdivision.org << de jolies applets Java en 3D, par l'auteur d'un bouquin traitant des subdivisions de surface

http://membres.lycos.fr/javamus/articles/subdivisions.html << très bon doc sur les subdivisions de surfaces en francais

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Renfield
Messages postés
17280
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
21 juillet 2019
57 -
Une chose a dire, beau boulot !!!! Je comptait utiliser un truc dans le genre pour mon projet (celui la, c'est mon bébé !!!) mais plus tard !!!!

voila un algo qui me propose cela directement a rajouter dans mon soft !! non, vraiment merci !!

et bravo pour toutes ces precisions......
Cyberdevil
Messages postés
483
Date d'inscription
mardi 10 juillet 2001
Statut
Membre
Dernière intervention
12 juillet 2006
-
bravo ! bon boulot !
Renfield
Messages postés
17280
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
21 juillet 2019
57 -
seule chose qui pourrait me voir retravailler l'algo pour qu'il me convienne tout a fait, c'est que je tiens absolument a conserver les points que j'ai définit. L'algo que tu nous propose les deplace en effet.

Si d'aventure tu avait quelque chose qui pourrait me convenir....

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.