Page 2 sur 2

Publié : ven. 26/juin/2009 20:05
par Cool Dji
kernadec a écrit :moi j'ai raté le bac, je suis tombé a l'eau
mdr :lol:

Publié : ven. 26/juin/2009 20:59
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

Publié : ven. 26/juin/2009 21:46
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.

Publié : ven. 26/juin/2009 22:03
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

Publié : ven. 26/juin/2009 22:30
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 !

Publié : mar. 30/juin/2009 22:43
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


Publié : mar. 30/juin/2009 23:32
par kernadec
bonsoir Ollivier
wouaouuu !!! de pure Polybezier
magnifique démonstration
merci, pour ce code
Cordialement

Publié : mer. 01/juil./2009 0:02
par Huitbit
Il ne reste plus qu'à exploiter tout ça :D !

Publié : mer. 01/juil./2009 7:47
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:

Publié : jeu. 02/juil./2009 11:35
par Cool Dji
Yaouh Ollivier,

C'est vraiment classe, bravo pour le code.
Est-ce que je peux l'utiliser ?

Publié : jeu. 02/juil./2009 12:16
par Ollivier
Ben bien sûr! Tous les codes publiés sur ce forum sont faits pour ça!

Publié : ven. 10/juil./2009 9:00
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