IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

B-Splines et nœuds ouverts


Sujet :

Algorithmes et structures de données

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 9
    Points
    9
    Par défaut B-Splines et nœuds ouverts
    Bonjour,

    Une discussion similaire a déjà été ouverte sur ce forum : http://www.developpez.net/forums/d88...ux-extremites/ et malgré l'avoir lu et relu je n'ai pas réussi à résoudre mon problème. Désolé si ça vous semble être un doublon.

    Mon problème : je cherche à approximer une courbe à partir d'un nuage de point, pour cela j'utilise les B-Spline. Pour simplifier mes tests je code sous matlab.

    J'utilise les notations (apparemment elles plaisent aux modérateurs =p ) de Wikipedia : http://fr.wikipedia.org/wiki/B-spline pour faciliter la compréhension.
    J'ai 6 points de contrôle : P = { (0.5,3) ; (1,4) ; (2,2) ; (4,1) ; (5,3) ; (7,1) } et ma spline sera de degré n = 3.
    J'en déduis donc le nombre de nœuds m = nb_point_controle + d + 1 = 10. Jusque là tout vas bien (enfin je crois ^^).

    J'obtiens le point de ma Spline en t grâce à la formule donnée par wiki.

    Maintenant viens le choix des nœuds. Tant que je ne m'occupe pas de leur multiplicité tout vas bien mais dès que je désire imposer le passage de la courbe par les points extrèmes et non plus par l'origine; rien ne va plus, et je ne comprend vraiment pas d'où viens l'erreur...

    Voici ce que j'obtiens quand je n'augmente pas la multiplicité des nœuds extrêmes, c'est à dire que j'utilise le vecteur noeud {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    Pièce jointe 176824


    Et voila ce qui se passe lorsque j'utilise les noeuds : {0, 0, 0, 0, 1, 2, 3, 3, 3, 3}
    Pièce jointe 176825

    Ci dessous le code matlab associé (je vous épargne les plot et autres fioritures). Si vous n'êtes pas très familier avec matlab, dîtes le moi, je peux le retranscrire en pseudo code

    Fonction récursive calculant le Bj,n(t). La variable knot correspond à mon vecteur de nœuds (cad au ti si on suit les notations)
    Code matlab : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    function [ B ] = base( j, n, t, knot )
     
    if n < 1
        if ( (t >=  knot(j)) && (t < knot(j+1)) )
            B = 1;
        else
            B = 0;
        end
    else
        if ( (knot(j+n) == knot(j)) || (knot(j+n+1) == knot(j+1)) )
            B = 0;
        else
            B = ((t - knot(j)) / (knot(j+n) - knot(j))) * base(j, n-1, t, knot) + (knot(j+n+1) - t) / (knot(j+n+1) - knot(j+1)) * base(j+1, n-1, t, knot);
        end
    end


    Et ce qui correspondrait à mon main :

    Code matlab : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    P = [0.5,3;
        1,4;
        2,2;
        4,1;
        5,3;
        7,1];
     
    knot = [0,1,2,3,4,5,6,7,8,9];
    %  knot = [0,0,0,0,1,2,3,3,3,3]; Si on veut des Noeuds ouverts
     
    cp = 0;
    for t = 0:0.1:9
        cp = cp + 1;
        S(cp, :) = [0 0];
        for j = 1:length(P)
            S(cp,:) = S(cp,:) + base(j, 3, t, knot) * P(j, :);
        end
    end

    Voilà je pense qu'il y a un truc que j'ai pas pas capté avec le vecteur noeud ou alors un vilaine erreur de code...
    Merci d'avance pour votre aide !!

    Léonard

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 5
    Points : 9
    Points
    9
    Par défaut Shame On Me
    Il s'agissait en fait d'une bien vilaine erreur de code... Je ne sais pas si je dois être rassuré d'avoir bien compris les B-Spline ou être atterré d'avoir passé 2 jours à débugger sans remarquer un truc aussi gros

    Bref le problème venait du test des dénominateurs (pour éviter la division par zéro) dans la fonction base.
    Je met le bon code ci-dessous au cas où ça intéresserait quelqu'un.

    Code matlab : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    function [ B ] = base( i, k, t, knot )
     
    B = 0;
    if k < 1
        if ( (t >= knot(i)) && (t < knot(i+1)) )
            B = 1;
        end
    else
        if knot(i+k) ~= knot(i)
            B = (t - knot(i)) / (knot(i+k) - knot(i)) * base(i, k-1, t, knot);
        end
     
        if knot(i+k+1) ~= knot(i+1)
            B = B + (knot(i+k+1) - t) / (knot(i+k+1) - knot(i+1)) * base(i+1, k-1, t, knot);
        end
    end


    @ +

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 28/02/2007, 12h18
  2. [VB6] Savoir depuis VB, si un document Excel est ouvert
    Par Argonz dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 12/11/2002, 08h16
  3. [TP]Splines
    Par Eric Sigoillot dans le forum Turbo Pascal
    Réponses: 3
    Dernier message: 30/06/2002, 19h08
  4. Accès à une application ouverte (OLE Automation ?)
    Par PascalB dans le forum C++Builder
    Réponses: 6
    Dernier message: 17/06/2002, 14h39
  5. Nombre de fichiers ouverts simultanément
    Par matrixfan dans le forum C++Builder
    Réponses: 3
    Dernier message: 27/05/2002, 17h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo