Subdivisions d'une courbe(création d'un circuit)+screenshots

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Message par Cool Dji »

kernadec a écrit :moi j'ai raté le bac, je suis tombé a l'eau
mdr :lol:
Only PureBasic makes it possible
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Message par kernadec »

bon il est vrai que la courbe de Huitbit à beaucoup de point rapprochés
cela limite l'investigation
mais pour la courbe d'Ollivier, c'est une courbe Bspline
car j'ai pu essayer plusieurs tracer et avec les BSplines
c'est quasiment identique a peu de chose prés
en prenant bien sur les points d'encrages du tracer.

cordialement
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Si ça peut vous rassurer, il n' y a pas besoin de Baccalauréat pour comprendre cet algo. . Il y a deux toutes petites modifications à faire dans mon code pour comprendre l'astuce.

Ligne 262: Décommentez cette ligne pour qu'elle puisse s'exécuter. ça permettra d'afficher des bornes bleues indifférentes aux clics de la souris.

Ligne 270: Enlevez juste le petit chiffre 2 derrière le nom de procédure DispLines. ça permet de commuter le type d'affichage de la courbe.

Ainsi, on voit mieux les coulisses de cette algo. . Chaque portion de courbe s'effectue dans un triangle (deux sommets bleu et un sommet rouge) en partant d'un sommet bleu vers un sommet rouge pour terminer sa course sur le sommet bleu suivant.

Pour chaque courbe on a : Bleu >> Rouge >> Bleu.
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Message par kernadec »

merci, Ollivier
pour ses informations je vais regarder ca.
car je n'ai eu bcp de temps pour étudier ton code
j'ai un source pour bspline qui n'est pas en purebasic

je te le transmet je ne sais plus ou je l'ai eu, je l'avais mis sous le coude
pour essayer d'en tirer quelques chose le moment venu.

cordialement

Code : Tout sélectionner

Main source code:

public struct point
{
public int x;
public int y;
public void setxy(int i,int j)
{
x=i;
y=j;
}
public void clearxy()
{
x=0;
y=0;
}
}
public void BSPLINE(point p1,point p2,point p3,point p4,int divisions)
{
double []a=new double[4];
double []b=new double[4];
a[0] = ( -p1.x + 3*p2.x - 3*p3.x + p4.x)/6.0;
a[1] = ( 3*p1.x - 6*p2.x + 3*p3.x )/6.0;
a[2] = (-3*p1.x + 3*p3.x )/6.0;
a[3] = ( p1.x + 4*p2.x + p3.x )/6.0;
b[0] = ( -p1.y + 3*p2.y - 3*p3.y + p4.y)/6.0;
b[1] = ( 3*p1.y - 6*p2.y + 3*p3.y )/6.0;
b[2] = (-3*p1.y + 3*p3.y )/6.0;
b[3] = ( p1.y + 4*p2.y + p3.y )/6.0;
spline_out_x[0] = a[3];
spline_out_y[0] = b[3];
For (int i = 1 ; i < divisions ; i++)
{
float t;
t = ((float) i) / ((float) divisions);
spline_out_x[i] = a[3] + t*(a[2] + t*(a[1] + t*a[0]));
spline_out_y[i] = b[3] + t*(b[2] + t*(b[1] + t*b[0]));
}
} 
public void plus_draw(int x,int y,int pen_width,Color cl )
{
Graphics g = Graphics.FromHwnd(this.Handle);
g.DrawLine(new Pen(cl,pen_width) ,x-3,y,x+3,y);
g.DrawLine(new Pen(cl,pen_width) ,x,y-3,x,y+3);
}
public void Form_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
If (Movement_Click>3)
{
pt[0]=pt[1];
pt[1]=pt[2];
pt[2]=pt[3];
pt[3].setxy(e.X,e.Y);
int no_of_interpolated_points=(int)(Math.Sqrt(Math.Pow((pt[2].x-pt[1].x),2)+Math.Pow((pt[2].y-pt[1].y),2)));
BSPLINE(pt[0],pt[1],pt[2],pt[3],no_of_interpolated_points);
For (int i=0;i<no_of_interpolated_points;i++)
plus_draw((int )spline_out_x[i],(int)spline_out_y[i],2,Color.Blue);
}
Else
{
pt[Movement_Click].setxy(e.X,e.Y);
}
Movement_Click=Movement_Click+1;
plus_draw(e.X,e.Y,1,Color.Red);
} 
je viens de mettre les interrupteurs de ton code
en fonction!
eh bien, les shemas de bspline que j'ai utilisés fonctionnent
de la même manière ce sont des structures polygonales, excellent.

merci, Ollivier pour ce code.
cordialement
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

@Ollivier
Ligne 262: Décommentez cette ligne pour qu'elle puisse s'exécuter. ça permettra d'afficher des bornes bleues indifférentes aux clics de la souris.

Ligne 270: Enlevez juste le petit chiffre 2 derrière le nom de procédure DispLines. ça permet de commuter le type d'affichage de la courbe.
:D Bien vu!

Bonne idée, l'objectif est quand même de créer un circuit ou un rail où les objets peuvent se déplacer !
Pour la suite, j'ai prévu d'appliquer ce que j'avais fait pour un solide glissant sur un rail.

@kernadec
bon il est vrai que la courbe de Huitbit a beaucoup de points rapprochés
On part de quelques points mais il faut aussi tenir compte du rapport que j'ai choisi arbitrairement. Les comparaisons sont donc difficiles, tu as raison!

Hasta la vista !
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

HuitBit a écrit :l'objectif est quand même de créer un circuit ou un rail où les objets peuvent se déplacer !
C'est mieux ça?

Code : Tout sélectionner

Structure PointInfo
   x.F
   y.F
   Level.I
   *Before
   *After
EndStructure

Structure Vertex2
   x.F
   y.F
EndStructure

Structure LineInfo
   x1.F
   y1.F
   x2.F
   y2.F
EndStructure

   Global NewList Pt.PointInfo()
   Global LevelMax.I = 2
   Global MarkQty.I = 20
   Global Dim Ln.LineInfo(999)
   Global MaxLine.I
   Global Dim Lb.Vertex2(999)
   Global MaxPoint.I

Procedure Inter(xA1.F, yA1.F, xA2.F, yA2.F, xB1.F, yB1.F, xB2.F, yB2.F, *A.Vertex2)

   Protected dxA.F
   Protected dyA.F   
   Protected dxB.F
   Protected dyB.F   
   Protected mA.F
   Protected pA.F   
   Protected mB.F
   Protected pB.F   
   Protected x.F
   Protected y.F

   dxA = xA1 - xA2
   dyA = yA1 - yA2
   dxB = xB1 - xB2
   dyB = yB1 - yB2
   
   If dxA = 0.0
      mB = dyB / dxB
      pB = yB1 - (mB * xB1)
      x = xA1
      y = mB * x + pB
   Else
      If dxB = 0.0
         mA = dyA / dxA
         pA = yA1 - (mA * xA1)
         x = xB1
         y = mA * x + pA
      Else
         mA = dyA / dxA
         pA = yA1 - (mA * xA1)

         mB = dyB / dxB
         pB = yB1 - (mB * xB1)

         x = (pB - pA) / (mA - mB)
         y = mA * x + pA
      EndIf
   EndIf

   
   *A\x = x
   *A\y = y
   
EndProcedure

Procedure InsertPoints(Level)
   Protected x1.F
   Protected y1.F
   Protected x2.F
   Protected y2.F
   SelectElement(Pt(), 0)
   *Start = Pt()
   ForEach(Pt() )
      If Pt() = *Start
         *After = *Start
         x2 = Pt()\x
         y2 = Pt()\y
      Else
         If Pt()\Level < Level
            *Before = *After
            x1 = x2
            y1 = y2
            *After = Pt()
            x2 = Pt()\x
            y2 = Pt()\y
            InsertElement(Pt() )
            Pt()\Level = Level
            Pt()\x = (x1 + x2) / 2.0
            Pt()\y = (y1 + y2) / 2.0
            Pt()\Before = *Before
            Pt()\After = *After
            NextElement(Pt() )
         EndIf
      EndIf
   Next
   ; Suite rajoutée pour la continuité
   ChangeCurrentElement(Pt(), *Start)
   If Pt()\Level < Level
      *Before = *After
      x1 = x2
      y1 = y2
      *After = Pt()
      x2 = Pt()\x
      y2 = Pt()\y
      InsertElement(Pt() )
      Pt()\Level = Level
      Pt()\x = (x1 + x2) / 2.0
      Pt()\y = (y1 + y2) / 2.0
      Pt()\Before = *Before
      Pt()\After = *After
      NextElement(Pt() )
   EndIf
EndProcedure

Procedure UpdatePoints()
   Protected x1.F
   Protected y1.F
   Protected x2.F
   Protected y2.F
   For I = 1 To LevelMax
      ForEach(Pt() )
         If Pt()\Level = I
            *Normal = Pt()
            *Before = Pt()\Before
            *After =  Pt()\After
            ChangeCurrentElement(Pt(), *Before)
            x1 = Pt()\x
            y1 = Pt()\y
            ChangeCurrentElement(Pt(), *After)
            x2 = Pt()\x
            y2 = Pt()\y
            ChangeCurrentElement(Pt(), *Normal)
            Pt()\x = (x1 + x2) / 2.0
            Pt()\y = (y1 + y2) / 2.0         
         EndIf
      Next
   Next
EndProcedure

Procedure CalculateLines()
   Protected x0.F
   Protected y0.F
   Protected x1.F
   Protected y1.F
   Protected x2.F
   Protected y2.F
   Protected x3.F
   Protected y3.F
   Protected vxA.F
   Protected vyA.F
   Protected vxB.F
   Protected vyB.F
   Protected xA.F
   Protected yA.F
   Protected xB.F
   Protected yB.F
   Protected Pas.F
   Protected P.Vertex2
   Pas = 10.0
   MaxLine = -1
   OpStep = 0
   MaxPoint = -1
   For J = 0 To 1
      ForEach Pt()
         Select OpStep
            Case 0
               If Pt()\Level = 1
                  x1 = Pt()\x
                  y1 = Pt()\y
                  x0 = x1
                  y0 = y1
                  OpStep = 1
               EndIf
            Case 1
               If Pt()\Level = 0
                  x2 = Pt()\x
                  y2 = Pt()\y
                  OpStep = 2
               EndIf   
            Case 2
               If Pt()\Level = 1
                  x3 = Pt()\x
                  y3 = Pt()\y
                  vxA = (x2 - x1) / (Pas + 1.0)
                  vyA = (y2 - y1) / (Pas + 1.0)
                  vxB = (x3 - x2) / (Pas + 1.0)
                  vyB = (y3 - y2) / (Pas + 1.0)
                  xA = x1
                  yA = y1
                  xB = x2
                  yB = y2
                  For I = 0 To Pas
                     MaxLine + 1
                     Ln(MaxLine)\x1 = xA
                     Ln(MaxLine)\y1 = yA
                     Ln(MaxLine)\x2 = xB
                     Ln(MaxLine)\y2 = yB
                     If MaxLine > 0
                        With Ln(MaxLine - 1)
                           Inter(\x1, \y1, \x2, \y2, xA, yA, xB, yB, @P)
                        EndWith
                        MaxPoint + 1
                        Lb(MaxPoint)\x = P\x
                        Lb(MaxPoint)\y = P\y
                     EndIf
                     xA + vxA
                     yA + vyA
                     xB + vxB
                     yB + vyB
                  Next
                  OpStep = 1
                  x1 = x3
                  y1 = y3
                  If J = 1
                     Break 2
                  EndIf
               EndIf
         EndSelect
      Next
   Next
   MaxPoint + 1
   Lb(MaxPoint)\x = x0
   Lb(MaxPoint)\y = y0
EndProcedure

Procedure DispLines()
   For I = 0 To MaxLine
      LineXY(Ln(I)\x1, Ln(I)\y1, Ln(I)\x2, Ln(I)\y2, #White)
   Next I
EndProcedure

Procedure DispLines2()
   For I = 1 To MaxPoint
      LineXY(Lb(I - 1)\x, Lb(I - 1)\y, Lb(I)\x, Lb(I)\y, #White)
   Next I
EndProcedure

Procedure DispLines3()
   DrawingMode(#PB_2DDrawing_Outlined)
   For I = 0 To MaxPoint
      Circle(Lb(I)\x, Lb(I)\y, 32, #White)
   Next I
EndProcedure

Procedure DispLines4()
   DrawingMode(#PB_2DDrawing_Outlined)
   For I = 0 To MaxPoint
      Box(Lb(I)\x, Lb(I)\y, 1, 1, #White)
   Next I
EndProcedure

Procedure DispLines5()
   Protected dx.F
   Protected dy.F
   Protected x0.F
   Protected y0.F
   Protected x1.F
   Protected y1.F
   Protected Angle.F
   Protected J.I
   Protected DeltaX.F
   Protected DeltaY.F
   For I = 0 To MaxPoint
      J = I - 1
      If J < 0
         J = MaxPoint
      EndIf
      x0 = Lb(J)\x
      y0 = Lb(J)\y
      J = I + 1
      If J > MaxPoint
         J = 0
      EndIf
      x1 = Lb(J)\x
      y1 = Lb(J)\y
      DeltaX = x1 - x0
      DeltaY = y1 - y0
      Angle = ACos(DeltaX / Sqr((DeltaX * DeltaX) + (DeltaY * DeltaY) ) )
      If DeltaY < 0.0
         Angle = 0.0 - Angle
      EndIf
      dx = Cos(Angle + #PI / 2.0) * 2.0
      dy = Sin(Angle + #PI / 2.0) * 2.0
      LineXY(Lb(I)\x - dx, Lb(I)\y - dy, Lb(I)\x + dx, Lb(I)\y + dy, #White)
   Next I
EndProcedure

   For I = 1 To MarkQty
      Angle.F = (I - 1) * 2.0 * #PI / MarkQty
      AddElement(Pt() )
      Pt()\x = 512 + Sin(Angle) * 200.0
      Pt()\y = 384 + Cos(Angle) * 200.0
   Next

   For I = 1 To LevelMax
      InsertPoints(I)
   Next
   InitSprite()
   InitMouse()
   OpenScreen(1024, 768, 32, "")
   
   Repeat
      Delay(1)
      ExamineMouse()
      MX = MouseX()
      MY = MouseY()
      MDX = MouseDeltaX()
      MDY = MouseDeltaY()
      MB1 = MouseButton(1)
      If MB1 = 0
         If MovePoint
            MovePoint = 0
            CalculateLines()
         EndIf
      Else
         UpdatePoints()
      EndIf
      ClearScreen(0)
      StartDrawing(ScreenOutput() )
         ForEach(Pt() )
            If Pt()\Level = 0
               If MB1
                  If (Abs(MX - Pt()\x) <= 8) And (Abs(MY - Pt()\y) <= 8)
                     MovePoint = 1
                     PointToMove = Pt()
                  EndIf
               EndIf
               Box(Pt()\x-8, Pt()\y-8, 16, 16, #Red)         
            EndIf
            If Pt()\Level = 1
               ;Box(Pt()\x-8, Pt()\y-8, 16, 16, #Blue)
            EndIf
            If Pt()\Level = 2
               ;Box(Pt()\x-8, Pt()\y-8, 16, 16, #Green)
            EndIf
         Next
         CalculateLines()
         UpdatePoints()
         DispLines5()
         If MovePoint
            ChangeCurrentElement(Pt(), PointToMove)
            Pt()\x + MDX
            Pt()\y + MDY
         EndIf
         Line(MX, MY, 16, 16, #White)
      StopDrawing()
      FlipBuffers()
   Until MouseButton(2)
   End

Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Message par kernadec »

bonsoir Ollivier
wouaouuu !!! de pure Polybezier
magnifique démonstration
merci, pour ce code
Cordialement
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Il ne reste plus qu'à exploiter tout ça :D !
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

un rigolo sérieux le Pierre (et ses liens associés! ) 8)

Un sacré bricolo de génie! 8O

Il y a de la lecture mais on voit comment on peut luter contre l'administration crasse :lol:
Est beau ce qui plaît sans concept :)
Speedy Galerie
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Message par Cool Dji »

Yaouh Ollivier,

C'est vraiment classe, bravo pour le code.
Est-ce que je peux l'utiliser ?
Only PureBasic makes it possible
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Ben bien sûr! Tous les codes publiés sur ce forum sont faits pour ça!
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Message par kernadec »

bonjour
j'ai trouvé un exemple très bien fait de courbes mathématiques.
il permet de se rendre compte des différences obtenue pour chaque tracé.
désolé, il est en Visual basic mais avec un petit exécutable, nul besoin de Visual basic pour tester ces courbes, voila l'adresse:

http://www.vbfrance.com/code.aspx?ID=18366

Cordialement
Répondre