FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC

Développement d'applications avec le langage Panoramic
 
AccueilAccueil  FAQFAQ  RechercherRechercher  S'enregistrerS'enregistrer  MembresMembres  GroupesGroupes  Connexion  
Derniers sujets
» KGF.dll - demandes ou suggestions de modifications ou ajouts
par Klaus Aujourd'hui à 19:48

» KGF_dll - nouvelles versions
par pascal10000 Aujourd'hui à 17:27

» Mah-Jong européen new-look
par Minibug Hier à 22:31

» track_bar circulaire
par Klaus Hier à 13:54

» API Windows
par Klaus Hier à 3:21

» Cartes de voeux, menus, etc.
par JL35 Lun 11 Déc 2017 - 17:48

» a l'aide klaus
par Minibug Lun 11 Déc 2017 - 11:42

» bug SYNEDIT_TARGET_IS_OBJECT
par Jack Lun 11 Déc 2017 - 0:16

» Jukebox : Serge Reggiani
par papydall Sam 9 Déc 2017 - 5:58

» Ecouter la radio fm sur votre pc
par pascal10000 Sam 9 Déc 2017 - 3:42

» anomalie
par Klaus Sam 9 Déc 2017 - 3:21

» hommage
par Jicehel Ven 8 Déc 2017 - 11:29

» Logiciel de soutien scolaire en langues.
par Pedro Alvarez Ven 8 Déc 2017 - 10:43

» carte son
par Klaus Ven 8 Déc 2017 - 2:37

» mise a jour calculatrice
par joeeee2017 Mer 6 Déc 2017 - 22:19

Navigation
 Portail
 Index
 Membres
 Profil
 FAQ
 Rechercher
Rechercher
 
 

Résultats par :
 
Rechercher Recherche avancée
Décembre 2017
LunMarMerJeuVenSamDim
    123
45678910
11121314151617
18192021222324
25262728293031
CalendrierCalendrier

Partagez | 
 

 B-SPLINES

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
papydall

avatar

Nombre de messages : 5613
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: B-SPLINES   Mar 23 Avr 2013 - 5:43

Voici un programme de calcul et de tracé des fonctions B-splines.

Les fonctions B-splines sont utilisées dans tous les problèmes d’interpolation et d’approximation aussi bien dans le plan que dans l’espace.
Ce sont des fonctions polynômiales par morceaux, c.à.d. des segments de polynômes de degré constant.
Ce degré détermine la « régularité » de la courbe obtenue.
Avec des polynômes de degré 2, on obtient des courbes lisses c.à.d. dérivables.
Avec des polynômes de degré 3, elles ont, en plus, la propriété de n’avoir pas de rupture brusque de courbure (elles sont 2 fois dérivables).
Le programme ci-après, utilise des B-splines d’ordre 2.

Le programme vous demande de lui indiquer le nombre d'une série de points (au moins 3, plus c'est mieux !) puis les coordonnées de ces points.
Il affiche à l'écran ces points sous forme de petits cercles, puis calcule et trace la courbe la plus harmonieuse qui les relie au plus près, mais sans nécessairement passer juste dessus.

Plus la série contient des points, meilleure sera la courbe.
Le minimum est de 3 points, le maximum est illimité , mais restons raisonnables !

Code:
' ******************************************************************************
'                  B-SPLINES.BAS
'                  PAR PAPYDALL
' ******************************************************************************
' Le programme vous demande de lui indiquer le nombre d'une série de points (au
' moins 3) puis les coordonnées de cette série.
' Il les affiche à l'écran sous forme de petits cercles , puis calcule et trace
' la courbe la plus harmonieuse qui les relie au plus près, mais sans
' nécessairement passer juste dessus.

init() : Saisie() : Calcul()
end
' ******************************************************************************
SUB Init()
    dim n,rep$,i,i1,i2,ip,xp,yp,k,kn,dt
    caption 0,"B-SPLINES"
    repeat
      repeat
        rep$ = message_input$("Nombre de points", "N > 2" , "5")
      until numeric(rep$) > 0
      n = val(rep$) - 1
    until n > 1
    dim p(n,2)
END_SUB
' ******************************************************************************
' Saisie des coordonnées des points
SUB Saisie()
    for i = 0 to n
        repeat
          rep$ = message_input$("Coordonnées du point "+str$(i+1), "X"+str$(i+1)+" =" , "")
        until numeric(rep$) > 0
        p(i,1) = val(rep$)
        repeat
          rep$ = message_input$("Coordonnées du point "+str$(i+1), "Y"+str$(i+1)+" =" , "")
        until numeric(rep$) > 0
        p(i,2) = val(rep$)
        2d_pen_color 255,0,0 : 2d_circle p(i,1),p(i,2),2
    next i
END_SUB
' ******************************************************************************
SUB Calcul()
    if label("nexti") = 0 then label nexti
    2d_pen_color 0,0,255 : 2d_poly_from p(0,1),p(0,2)
    for ip = 0 to n-1+.001  step .05
        xp = 0 : yp = 0
        for i = 0 to n
            if ip < i-2 then goto nexti
            if ip > i+1 then goto nexti
            if ip < i-1
              i1 = i : calcul_kn() : k = kn
              i1 = i+2 : calcul_kn() : dt = kn - k
              if dt = 0 then goto nexti
              xp = xp+p(i,1) * (ip-(i-2)) * (ip-(i-2))/dt
              yp = yp+p(i,2) * (ip-(i-2)) * (ip-(i-2))/dt
              goto nexti
            end_if
            if ip < i
              i1 = i : calcul_kn() : k = kn
              i1 = i+2 : calcul_kn() : dt = kn-k
              if dt <> 0
                  i1 = i : calcul_kn() : i2 = kn
                  xp = xp + p(i,1) * (ip-i2) * (i-ip)/dt
                  yp = yp + p(i,2) * (ip-i2) * (i-ip)/dt
              end_if
              i1 = i+1 : calcul_kn() : k = kn
              i1 = i+3 : calcul_kn() : dt = kn-k
              if dt = 0 then goto nexti
              i1 = i + 3 : calcul_kn() : i2 = kn
              xp = xp + p(i,1) * (i2-ip) * (ip-(i-1))/dt
              yp = yp + p(i,2) * (i2-ip) * (ip-(i-1))/dt
              goto nexti
            end_if
            i1 = i + 1 : calcul_kn() : k = kn
            i1 = i + 3 : calcul_kn() : dt = kn - k
            if dt = 0 then goto nexti
            xp = xp + p(i,1) * ((i+1)-ip) * ((i+1)-ip)/dt
            yp = yp + p(i,2) * ((i+1)-ip) * ((i+1)-ip)/dt
nexti:
        next i
        if ip = n-1 then 2d_poly_to p(n,1),p(n,2) : exit_sub
        2d_poly_to xp,yp
    next ip
END_SUB
' ******************************************************************************
SUB calcul_kn()
    kn = i1 - 2 : if kn < 0 then kn = 0
    if kn > n-1 then kn = n-1
END_SUB
' ******************************************************************************
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Jicehel

avatar

Nombre de messages : 5863
Age : 45
Localisation : 77500
Date d'inscription : 19/04/2011

MessageSujet: Re: B-SPLINES   Mar 23 Avr 2013 - 8:05

Bien. A mon avis, par contre, pour le côté mathématiques, tu aurais dû ajouter une fonction au départ de mise à l'echelle en fonction des valeurs (notamment s'il y a des valeurs négatives).
Si on veut un repère ortho, il faut calculer l'amplitude en X et l'amplitude en Y pour connaitre la plus grande amplitude qui servirait pour avoir les valeurs max (obligé si on veut un repère ortho sinon on passe à l'étape suivante)
Tu mettrais à gauche la valeur la plus faible en X à droite de l'écran, la plus haute.
En bas tu mettrais la plus faible en y et en haut la plus grande.
Après, éventuellement, possibilité de tracer ou non les axes, mais là, c'est pareil, en fonction de l'amplitude il faut calculer le pas de la graduation.
Je pense que ce serait sympa au niveau visuel si l'on travail sur une petite amplitude ou au contraire sur une grande ou si on a des valeurs négatives.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
papydall

avatar

Nombre de messages : 5613
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: B-SPLINES   Mar 23 Avr 2013 - 19:14

@Jicehel
Tes remarques sont judicieuses.
J’essayerai de les appliquer quand j’aurai une heure de libre, peut-être cette nuit.
A+
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
papydall

avatar

Nombre de messages : 5613
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: B-SPLINES   Ven 26 Avr 2013 - 5:02

Voilà c’est fait.
Le code est suffisamment documenté : Plusieurs lignes REM expliquent le fonctionnement.
Je vous mets le code tel quel et chacun (s’il veut bien) peut l’adapter à sa façon.
Code:
' ******************************************************************************
'                  B-SPLINES.BAS
'                  PAR PAPYDALL
' ******************************************************************************
' Le programme vous demande de lui indiquer le nombre d'une série de points (au
' moins 3) puis les coordonnées de cette série.
' Ces coordonnées peuvent être positives, nulles ou négatives.
' Il n'est pas obligatoire que les abscisses soient croissantes : en effet, la
' courbe résultante peut présenter une ou plusieurs boucles.
' Le programme affiche à l'écran la série sous forme de gros points , puis
' calcule et trace les 2 axes en les graduant.
' En fin il trace la courbe la plus harmonieuse qui les relie au plus près, mais
' sans nécessairement passer juste dessus.
' La courbe obtenue est une B-SPLINE (prononcez B-SPLAÏNE à l'anglaise)

' Ce programme peut être utilisé pour modéliser des objets qui ne sont pas
' exclusivement constitués de lignes droites mais comprennent aussi des contours.
' ******************************************************************************
Run()
end
' ******************************************************************************
SUB Run()
    Variables_reservees()
    init() : Saisie() : full_space 0
    G_v1 = 50 : G_v2 = width(0)-50 : G_v3 = 50 : G_v4 = height(0)-100 : ' Clôture
    G_u = int((G_w2 - G_w1) /10) : G_v = int((G_w4 -G_w3)/10) : ' Unités sur les axes X et Y
    Init_Graphe() : Point_Cercle() : Trace_Axes() : Graduer_Axes() : calcul()

    alpha 5  : top 5, 10 : font_bold 5 : Caption 5,"Unités sur les axes"
    alpha 10 : top 10,30 : font_bold 10
    caption 10,"Axe X : U = " + str$(G_u) + "  Axe Y : V = " +str$(G_v)
END_SUB
' ******************************************************************************
SUB Init()
    dim n,rep$,kn,x,y
    caption 0,"B-SPLINES PAR PAPYDALL"
    repeat
      repeat
        rep$ = message_input$("Nombre de points de la série", "N > 2" , "10")
      until numeric(rep$) > 0
      n = val(rep$) - 1
    until n > 1
    dim p(n,2)
END_SUB
' ******************************************************************************
' Saisie des coordonnées des points
SUB Saisie()
    dim_local i,rep$
    for i = 0 to n
        repeat
          rep$ = message_input$("Coordonnées du point "+str$(i+1), "X"+str$(i+1)+" =" , "")
        until numeric(rep$) > 0
        p(i,1) = val(rep$)
' Détermination de la largeur de la fenêtre de vision
        If p(i,1) < G_w1 then G_w1 = p(i,1)
        if p(i,1) > G_w2 then G_w2 = p(i,1)
       
        repeat
          rep$ = message_input$("Coordonnées du point "+str$(i+1), "Y"+str$(i+1)+" =" , "")
        until numeric(rep$) > 0
        p(i,2) = val(rep$)
' Détermination de la hauteur de la fenêtre de vision
        if p(i,2) < G_w3 then G_w3 = p(i,2)
        if p(i,2) > G_w4 then G_w4 = p(i,2)
       
    next i
END_SUB
' ******************************************************************************
' Affichage des points de la série sous forme de petits cercle pleins
sub Point_Cercle()
    dim_local i
    Init_Graphe()
    for i = 0 to n
        x  = p(i,1) : y = p(i,2) : G_w$ = "U"
        2d_pen_color 255,0,0 : Trace_Rapide()
        2d_fill_color 0,0,0 : 2d_circle G_x5,G_y5,5
    next i
end_sub

' ******************************************************************************
SUB Calcul()
    dim_local i,i1,i2, ip ,xp,yp,k,dt
    if label("nexti") = 0 then label nexti
    x = p(0,1) : y = p(0,2) : G_w$ = "U"
    2d_pen_color 0,0,255  : Trace_Rapide()

    for ip = 0 to n-1+0.01  step .05
        xp = 0 : yp = 0
        for i = 0 to n
            if ip < i-2 then goto nexti
            if ip > i+1 then goto nexti
            if ip < i-1
              i1 = i : calcul_kn(i1,n) : k = kn
              i1 = i+2 : calcul_kn(i1,n) : dt = kn - k
              if dt = 0 then goto nexti
              xp = xp+p(i,1) * (ip-(i-2)) * (ip-(i-2))/dt
              yp = yp+p(i,2) * (ip-(i-2)) * (ip-(i-2))/dt
              goto nexti
            end_if
            if ip < i
              i1 = i : calcul_kn(i1,n) : k = kn
              i1 = i+2 : calcul_kn(i1,n) : dt = kn-k
              if dt <> 0
                  i1 = i : calcul_kn(i1,n) : i2 = kn
                  xp = xp + p(i,1) * (ip-i2) * (i-ip)/dt
                  yp = yp + p(i,2) * (ip-i2) * (i-ip)/dt
              end_if
              i1 = i+1 : calcul_kn(i1,n) : k = kn
              i1 = i+3 : calcul_kn(i1,n) : dt = kn-k
              if dt = 0 then goto nexti
              i1 = i + 3 : calcul_kn(i1,n) : i2 = kn
              xp = xp + p(i,1) * (i2-ip) * (ip-(i-1))/dt
              yp = yp + p(i,2) * (i2-ip) * (ip-(i-1))/dt
              goto nexti
            end_if
            i1 = i + 1 : calcul_kn(i1,n) : k = kn
            i1 = i + 3 : calcul_kn(i1,n) : dt = kn - k
            if dt = 0 then goto nexti
            xp = xp + p(i,1) * ((i+1)-ip) * ((i+1)-ip)/dt
            yp = yp + p(i,2) * ((i+1)-ip) * ((i+1)-ip)/dt
nexti:
        next i
      if ip = n-1 then x = p(n,1) : y = p(n,2) : G_w$ = "D" : Trace_Rapide() : exit_sub
      x = xp : y = yp : G_w$ = "D" : Trace_rapide()
    next ip
END_SUB
' ******************************************************************************
SUB calcul_kn(i1,n)
    kn = i1 - 2 : if kn < 0 then kn = 0
    if kn > n-1 then kn = n-1
END_SUB
' ******************************************************************************
' ******************************************************************************
' ******************************************************************************
' Déclaration des variables reservées aux differentes procédures graphiques.
' -----------------------------
SUB Variables_reservees()
    dim G_a8,G_a9,G_b8,G_b9,G_p9,G_q9,G_t8,G_t9,G_u8,G_v8
    dim G_u,G_v, G_x5,G_x6,G_y5,G_y6,G_w$
    dim G_v1,G_v2,G_v3,G_v4 : ' Paramètres de la clôture
    dim G_w1,G_w2,G_w3,G_w4 : ' Paramètres de la fenêtre
END_SUB

' ******************************************************************************
SUB Init_Graphe()
    G_a8 = (G_v2-G_v1)/(G_w2-G_w1) : G_b8 = (G_v1*G_w2-G_v2*G_w1)/(G_w2-G_w1)
    G_a9 = (G_v4-G_v3)/(G_w4-G_w3) : G_b9 = (G_v3*G_w4-G_v4*G_w3)/(G_w4-G_w3)
END_SUB
' ******************************************************************************
' Projection et tracé
SUB Trace_rapide()
    G_x6 = x : G_y6 = y  : ' Tracé rapide sans coupage
    Projection()
END_SUB
' ------------------------------------------------------------------------------
SUB Projection()
    display
    G_x5 = G_a8 * G_x6 + G_b8 : G_y5 = height(0)-(G_a9 * G_y6 + G_b9)
    if G_w$ = "U" then 2d_poly_from G_x5,G_y5 : else : 2d_poly_to G_x5,G_y5
END_SUB
' ******************************************************************************
' Tracé des axes
' --------------
' Plusieurs cas peuvent se présenter :
' Si l'origine (0,0) appartient à la fenêtre, les axes sont tracés normalement
' et comprennent l'origine.
' Si l'origine est extérieure à la fenêtre alors les axes seront toujours
' confondus avec les 2 frontières inférieures de la fenêtre.
' Mais si un seul axe coupe la fenêtre, ce dernier sera tracé. L'autre axe étant
' confondu avec un des bords inférieur de la fenêtre.
SUB Trace_Axes()
' Au départ on initialise toujours l'origine des axes dans le coin inférieur
' gauche de la fenêtre, donc en (G_w1,G_w3)
    G_p9 = G_w1 : G_q9 = G_w3
' Si l'origine (0,0) appartient à la bande du plan limité par les droites X = G_w1
' et X = G_w2 alors l'axe Y est nécessairement vu, donc G_p9 = 0
    if G_w1 < 0 and G_w2 > 0 then G_p9 = 0
' Si l'origine (0,0) appartient à la bande de plan limité par les droites Y = G_w3
' et Y = G_w4 alors l'axe X est nécessairement vu, donc G_q9 = 0
    if G_w3 < 0 and G_w4 > 0 then G_q9 = 0
' Après ces 2 tests, on est certain que (G_p9,G_q9) représente bien l'origine réelle
' des axes ou l'origine fictive qu'on a décidé d'adopter
    G_x6 = G_w1 : G_y6 = G_q9 : G_w$ = "U" : Projection() : G_x6 = G_w2
    G_w$ = "D" : Projection()
    G_x6 = G_p9 : G_y6 = G_w3 : G_w$ = "U" : Projection() : G_y6 = G_w4
    G_w$ = "D" : Projection()
END_SUB
' ******************************************************************************
' Graduation des axes
' -------------------
SUB Graduer_Axes()
' G_t8 et G_t9 contiennent des longueurs valant respectivement 2% des frontières
' horizontales et verticales de la fenêtre.
    G_t8 = .02 *(G_w2-G_w1) : G_t9 = .02 *(G_w4-G_w3)
' G_u8 et G_v8 sont les facteurs correctifs éventuels à apporter
    if G_u = 0 then G_u = 1 : ' Pour éviter l'erreur fatale division par zéro
    if G_v = 0 then G_v = 1 : ' si on a oublié d'initialiser G_u et G_v
    G_u8 = ((G_p9-G_w1)/G_u - int((G_p9-G_w1)/G_u))*G_u
    G_v8 = ((G_q9-G_w3)/G_v - int((G_q9-G_w3)/G_v))*G_v
' On fait varier G_x6 du point de départ correct de la graduation jusqu'à la
' limite G_w2 de la fenêtre avec l'unité U pour pas
    for G_x6 = G_w1 + G_u8 to G_w2 step G_u
' On dessine la graduation sur l'axe X au moyen de la boucle d'index G_x6.
' Pour chaque trait, on se déplace d'abord plume levée au point convenable de
' l'axe X, puis plume baissée on trace un petit trait vertical de longueur G_t9
        G_y6 = G_q9 : G_w$ = "U" : Projection() : G_y6 = G_q9 + G_t9
        G_w$ = "D" : Projection()
    next G_x6
' Même technique pour les graduations sur l'axe Y
    for G_y6 = G_w3 + G_v8 to G_w4 step G_v
        G_x6 = G_q9 : G_w$ = "U" : Projection() : G_x6 = G_q9 + G_t9
        G_w$ = "D" : Projection()
    next G_y6
END_SUB
' ******************************************************************************
' Tracer un cadre
SUB Cadre()
    G_x6 = G_w1 : G_y6 = G_w3 : G_w$ = "U" : Projection() : G_x6 = G_w2
    G_w$ = "D" : Projection()
    G_y6 = G_w4 : Projection() : G_x6 = G_w1 :  Projection()
    G_y6 = G_w3 : Projection()
END_SUB
' ******************************************************************************
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Yannick

avatar

Nombre de messages : 8002
Age : 46
Localisation : Bretagne
Date d'inscription : 15/02/2010

MessageSujet: re   Ven 26 Avr 2013 - 5:14

Très Belle démonstration !!!!
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
papydall

avatar

Nombre de messages : 5613
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: B-SPLINES   Ven 26 Avr 2013 - 5:53

Molte grazie.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Jicehel

avatar

Nombre de messages : 5863
Age : 45
Localisation : 77500
Date d'inscription : 19/04/2011

MessageSujet: Re: B-SPLINES   Ven 26 Avr 2013 - 8:21

Oui, très bien. En plus, les graphistes peuvent l'utiliser pour faire du dessin mais bon, moi, je n'ai pas le niveau pour ça.
Seul mini critique: tu devrait dessiner la flèche au bout de la partie positive de l'axe, mais bon, la convention est respecté et normalement tout le monde connait le sens des axes, c'est donc un peu gadget.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
papydall

avatar

Nombre de messages : 5613
Age : 67
Localisation : Moknine (Tunisie) Entre la chaise et le clavier
Date d'inscription : 03/03/2012

MessageSujet: Re: B-SPLINES   Ven 26 Avr 2013 - 20:31

Pour la flèche en voici deux, plus un zéro pour l'origine.
Ce n’est pas bon bon mais bon c’est tout ce que je sais faire de bon !
Alors forcement ce n’est pas bon !

Code:
' ******************************************************************************
'                  B-SPLINES.BAS
'                  PAR PAPYDALL
' ******************************************************************************
' Le programme vous demande de lui indiquer le nombre d'une série de points (au
' moins 3) puis les coordonnées de cette série.
' Ces coordonnées peuvent être positives, nulles ou négatives.
' Il n'est pas obligatoire que les abscisses soient croissantes : en effet, la
' courbe résultante peut présenter une ou plusieurs boucles.
' Le programme affiche à l'écran la série sous forme de gros points , puis
' calcule et trace les 2 axes en les graduant.
' En fin il trace la courbe la plus harmonieuse qui les relie au plus près, mais
' sans nécessairement passer juste dessus.
' La courbe obtenue est une B-SPLINE (prononcez B-SPLAÏNE à l'anglaise)

' Ce programme peut être utilisé pour modéliser des objets qui ne sont pas
' exclusivement constitués de lignes droites mais comprennent aussi des contours.
' ******************************************************************************
Run()
end
' ******************************************************************************
SUB Run()
    Variables_reservees()
    init() : Saisie() : full_space 0
    G_v1 = 50 : G_v2 = width(0)-50 : G_v3 = 50 : G_v4 = height(0)-100 : ' Clôture
    G_u = int((G_w2 - G_w1) /10) : G_v = int((G_w4 -G_w3)/10) : ' Unités sur les axes X et Y
    Init_Graphe() : Point_Cercle() : Trace_Axes() : Graduer_Axes() : calcul()

    alpha 5  : top 5, 10 : font_bold 5 : Caption 5,"Unités sur les axes"
    alpha 10 : top 10,30 : font_bold 10
    caption 10,"Axe X : U = " + str$(G_u) + "  Axe Y : V = " +str$(G_v)
END_SUB
' ******************************************************************************
SUB Init()
    dim n,rep$,kn,x,y
    caption 0,"B-SPLINES PAR PAPYDALL"
    repeat
      repeat
        rep$ = message_input$("Nombre de points de la série", "N > 2" , "10")
      until numeric(rep$) > 0
      n = val(rep$) - 1
    until n > 1
    dim p(n,2)
END_SUB
' ******************************************************************************
' Saisie des coordonnées des points
SUB Saisie()
    dim_local i,rep$
    for i = 0 to n
        repeat
          rep$ = message_input$("Coordonnées du point "+str$(i+1), "X"+str$(i+1)+" =" , "")
        until numeric(rep$) > 0
        p(i,1) = val(rep$)
' Détermination de la largeur de la fenêtre de vision
        If p(i,1) < G_w1 then G_w1 = p(i,1)
        if p(i,1) > G_w2 then G_w2 = p(i,1)

        repeat
          rep$ = message_input$("Coordonnées du point "+str$(i+1), "Y"+str$(i+1)+" =" , "")
        until numeric(rep$) > 0
        p(i,2) = val(rep$)
' Détermination de la hauteur de la fenêtre de vision
        if p(i,2) < G_w3 then G_w3 = p(i,2)
        if p(i,2) > G_w4 then G_w4 = p(i,2)

    next i
END_SUB
' ******************************************************************************
' Affichage des points de la série sous forme de petits cercle pleins
sub Point_Cercle()
    dim_local i
    Init_Graphe()
    for i = 0 to n
        x  = p(i,1) : y = p(i,2) : G_w$ = "U"
        2d_pen_color 255,0,0 : Trace_Rapide()
        2d_fill_color 0,0,0 : 2d_circle G_x5,G_y5,5
    next i
end_sub

' ******************************************************************************
SUB Calcul()
    dim_local i,i1,i2, ip ,xp,yp,k,dt
    if label("nexti") = 0 then label nexti
    x = p(0,1) : y = p(0,2) : G_w$ = "U"
    2d_pen_color 0,0,255  : Trace_Rapide()

    for ip = 0 to n-1+0.01  step .05
        xp = 0 : yp = 0
        for i = 0 to n
            if ip < i-2 then goto nexti
            if ip > i+1 then goto nexti
            if ip < i-1
              i1 = i : calcul_kn(i1,n) : k = kn
              i1 = i+2 : calcul_kn(i1,n) : dt = kn - k
              if dt = 0 then goto nexti
              xp = xp+p(i,1) * (ip-(i-2)) * (ip-(i-2))/dt
              yp = yp+p(i,2) * (ip-(i-2)) * (ip-(i-2))/dt
              goto nexti
            end_if
            if ip < i
              i1 = i : calcul_kn(i1,n) : k = kn
              i1 = i+2 : calcul_kn(i1,n) : dt = kn-k
              if dt <> 0
                  i1 = i : calcul_kn(i1,n) : i2 = kn
                  xp = xp + p(i,1) * (ip-i2) * (i-ip)/dt
                  yp = yp + p(i,2) * (ip-i2) * (i-ip)/dt
              end_if
              i1 = i+1 : calcul_kn(i1,n) : k = kn
              i1 = i+3 : calcul_kn(i1,n) : dt = kn-k
              if dt = 0 then goto nexti
              i1 = i + 3 : calcul_kn(i1,n) : i2 = kn
              xp = xp + p(i,1) * (i2-ip) * (ip-(i-1))/dt
              yp = yp + p(i,2) * (i2-ip) * (ip-(i-1))/dt
              goto nexti
            end_if
            i1 = i + 1 : calcul_kn(i1,n) : k = kn
            i1 = i + 3 : calcul_kn(i1,n) : dt = kn - k
            if dt = 0 then goto nexti
            xp = xp + p(i,1) * ((i+1)-ip) * ((i+1)-ip)/dt
            yp = yp + p(i,2) * ((i+1)-ip) * ((i+1)-ip)/dt
nexti:
        next i
      if ip = n-1 then x = p(n,1) : y = p(n,2) : G_w$ = "D" : Trace_Rapide() : exit_sub
      x = xp : y = yp : G_w$ = "D" : Trace_rapide()
    next ip
END_SUB
' ******************************************************************************
SUB calcul_kn(i1,n)
    kn = i1 - 2 : if kn < 0 then kn = 0
    if kn > n-1 then kn = n-1
END_SUB
' ******************************************************************************
' ******************************************************************************
' ******************************************************************************
' Déclaration des variables reservées aux differentes procédures graphiques.
' -----------------------------
SUB Variables_reservees()
    dim G_a8,G_a9,G_b8,G_b9,G_p9,G_q9,G_t8,G_t9,G_u8,G_v8
    dim G_u,G_v, G_x5,G_x6,G_y5,G_y6,G_w$
    dim G_v1,G_v2,G_v3,G_v4 : ' Paramètres de la clôture
    dim G_w1,G_w2,G_w3,G_w4 : ' Paramètres de la fenêtre
END_SUB

' ******************************************************************************
SUB Init_Graphe()
    G_a8 = (G_v2-G_v1)/(G_w2-G_w1) : G_b8 = (G_v1*G_w2-G_v2*G_w1)/(G_w2-G_w1)
    G_a9 = (G_v4-G_v3)/(G_w4-G_w3) : G_b9 = (G_v3*G_w4-G_v4*G_w3)/(G_w4-G_w3)
END_SUB
' ******************************************************************************
' Projection et tracé
SUB Trace_rapide()
    G_x6 = x : G_y6 = y  : ' Tracé rapide sans coupage
    Projection()
END_SUB
' ------------------------------------------------------------------------------
SUB Projection()
    display
    G_x5 = G_a8 * G_x6 + G_b8 : G_y5 = height(0)-(G_a9 * G_y6 + G_b9)
    if G_w$ = "U" then 2d_poly_from G_x5,G_y5 : else : 2d_poly_to G_x5,G_y5
END_SUB
' ******************************************************************************
' Tracé des axes
' --------------
' Plusieurs cas peuvent se présenter :
' Si l'origine (0,0) appartient à la fenêtre, les axes sont tracés normalement
' et comprennent l'origine.
' Si l'origine est extérieure à la fenêtre alors les axes seront toujours
' confondus avec les 2 frontières inférieures de la fenêtre.
' Mais si un seul axe coupe la fenêtre, ce dernier sera tracé. L'autre axe étant
' confondu avec un des bords inférieur de la fenêtre.
SUB Trace_Axes()
' Au départ on initialise toujours l'origine des axes dans le coin inférieur
' gauche de la fenêtre, donc en (G_w1,G_w3)
    G_p9 = G_w1 : G_q9 = G_w3
' Si l'origine (0,0) appartient à la bande du plan limité par les droites X = G_w1
' et X = G_w2 alors l'axe Y est nécessairement vu, donc G_p9 = 0
    if G_w1 < 0 and G_w2 > 0 then G_p9 = 0
' Si l'origine (0,0) appartient à la bande de plan limité par les droites Y = G_w3
' et Y = G_w4 alors l'axe X est nécessairement vu, donc G_q9 = 0
    if G_w3 < 0 and G_w4 > 0 then G_q9 = 0
' Après ces 2 tests, on est certain que (G_p9,G_q9) représente bien l'origine réelle
' des axes ou l'origine fictive qu'on a décidé d'adopter

    G_x6 = G_w1 : G_y6 = G_q9 : G_w$ = "U" : Projection() : G_x6 = G_w2
    G_w$ = "D" : Projection()
   
' Flèche (pour le sens positif) sur l'axe X
    alpha 20 : top 20, G_y5-8 : left 20,G_x5 : font_color 20,255,0,0 : font_bold 20 : caption 20,">"

    G_x6 = G_p9 : G_y6 = G_w3 : G_w$ = "U" : Projection() : G_y6 = G_w4
    G_w$ = "D" : Projection()
' Flèche (pour le sens positif) sur l'axe Y
    alpha 21 : top 21, G_y5-8 : left 21,G_x5-3 : font_color 21,255,0,0 : font_bold 21 : caption 21,"^"
   
    G_x6 = G_q9 : G_y6 = G_p9 : G_w$ = "U" : Projection()
' Zéro pour l'origine
    alpha 19 : top 19, G_y5+10 : left 19,G_x5-10 : font_color 19,255,0,0 : font_bold 19 : caption 19,"0"

END_SUB
' ******************************************************************************
' Graduation des axes
' -------------------
SUB Graduer_Axes()
' G_t8 et G_t9 contiennent des longueurs valant respectivement 2% des frontières
' horizontales et verticales de la fenêtre.
    G_t8 = .02 *(G_w2-G_w1) : G_t9 = .02 *(G_w4-G_w3)
' G_u8 et G_v8 sont les facteurs correctifs éventuels à apporter
    if G_u = 0 then G_u = 1 : ' Pour éviter l'erreur fatale division par zéro
    if G_v = 0 then G_v = 1 : ' si on a oublié d'initialiser G_u et G_v
    G_u8 = ((G_p9-G_w1)/G_u - int((G_p9-G_w1)/G_u))*G_u
    G_v8 = ((G_q9-G_w3)/G_v - int((G_q9-G_w3)/G_v))*G_v
' On fait varier G_x6 du point de départ correct de la graduation jusqu'à la
' limite G_w2 de la fenêtre avec l'unité U pour pas
    for G_x6 = G_w1 + G_u8 to G_w2 step G_u
' On dessine la graduation sur l'axe X au moyen de la boucle d'index G_x6.
' Pour chaque trait, on se déplace d'abord plume levée au point convenable de
' l'axe X, puis plume baissée on trace un petit trait vertical de longueur G_t9
        G_y6 = G_q9 : G_w$ = "U" : Projection() : G_y6 = G_q9 + G_t9
        G_w$ = "D" : Projection()
    next G_x6

' Même technique pour les graduations sur l'axe Y
    for G_y6 = G_w3 + G_v8 to G_w4 step G_v
        G_x6 = G_q9 : G_w$ = "U" : Projection() : G_x6 = G_q9 + G_t9
        G_w$ = "D" : Projection()
    next G_y6
END_SUB
' ******************************************************************************
' Tracer un cadre
SUB Cadre()
    G_x6 = G_w1 : G_y6 = G_w3 : G_w$ = "U" : Projection() : G_x6 = G_w2
    G_w$ = "D" : Projection()
    G_y6 = G_w4 : Projection() : G_x6 = G_w1 :  Projection()
    G_y6 = G_w3 : Projection()
END_SUB
' ******************************************************************************
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://papydall-panoramic.forumarabia.com/
Contenu sponsorisé




MessageSujet: Re: B-SPLINES   

Revenir en haut Aller en bas
 
B-SPLINES
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
FORUM DE DISCUSSION SUR LE LANGAGE PANORAMIC :: PANORAMIC :: Vos sources, vos utilitaires à partager-
Sauter vers: