Bon, je poste ce que j'ai sur les courbes de bezier, c'est a mon avis ce que tu cherches, mais toi tu ne veux pas dessiner la courbe, juste avoir les coordonées des points.
Faudra que tu examines la procédure Bezier_recursive() pour cela
1er include : (je ne sais plus pourquoi j'avais fait ca mais bon.. c'est fait)
Code : Tout sélectionner
;{ JR_list ( permet de créer des listes chainées et de les modifier comme on le veut )
; ## module dépendance : none
Procedure JR_Create_linkedlist(taille_type); utiliser la commande SizeOf(type) pour obtenir taille_type
list_head = AllocateMemory(4 * 5)
PokeL(list_head + 16, taille_type)
; description de la tete de liste
; +0 : taille de la liste
; +4 : adresse du premier element
; +8 : adresse du dernier element
; +12 : adresse de l'element courant
; +16 : taille des elements de la liste
; description d'un element
; +0 : element precedent
; +4 : element suivant
; +8 : debut des données
ProcedureReturn list_head
EndProcedure
Procedure JR_Add_element(JR_list_id.l) ; ajoute un element en fin de liste et cet element devient celui en cours
new_element = AllocateMemory(PeekL(JR_list_id + 16) + 8)
ancien_dernier_element = PeekL(JR_list_id + 8)
If PeekL(JR_list_id)
PokeL(JR_list_id, PeekL(JR_list_id) + 1) ; nb element
PokeL(ancien_dernier_element + 4, new_element) ; mise a jour de l'ancien denier element
PokeL(new_element, ancien_dernier_element) ; adresse de l'element precedent
Else
PokeL(JR_list_id, 1) ; nb element
PokeL(JR_list_id + 4, new_element) ; premier element
EndIf
PokeL(JR_list_id + 8, new_element) ; dernier element
PokeL(JR_list_id + 12, new_element) ; element courant
EndProcedure
Procedure JR_Select_element(JR_list_id.l, num.l, option.l = 0) ; si option = 1 : l'element courant ne change pas, la fonction retourne l'adresse de l'element à la position num
nb_elem = PeekL(JR_list_id)
If num > nb_elem Or num < 1: ProcedureReturn 0 : EndIf
dist_first = num - 1
dist_last = nb_elem - num
If dist_first < dist_last
adresse = PeekL(JR_list_id + 4)
delta = dist_first
Else
adresse = PeekL(JR_list_id + 8)
delta = -dist_last
EndIf
If delta < 0 : ad = 0 : EndIf
If delta > 0 : ad = 4 : EndIf
For a = 1 To Abs(delta)
adresse = PeekL(adresse + ad)
Next
PokeL(JR_list_id + 12, adresse)
ProcedureReturn adresse
EndProcedure
Procedure JR_Next_element(JR_list_id.l) ; retourne l'adresse de l'élément suivant, et le change en element courant
adresse_current = PeekL(JR_list_id + 12)
If adresse_current
If PeekL(adresse_current + 4)
PokeL(JR_list_id + 12, PeekL(adresse_current + 4))
ProcedureReturn JR_list_id
EndIf
Else
PokeL(JR_list_id + 12, PeekL(JR_list_id + 4))
ProcedureReturn JR_list_id
EndIf
EndProcedure
Procedure JR_Previous_element(JR_list_id.l) ; retourne l'adresse de l'élément précedent, et le change en element courant
adresse_current = PeekL(JR_list_id + 12)
If adresse_current
If PeekL(adresse_current)
PokeL(JR_list_id + 12, PeekL(adresse_current))
ProcedureReturn JR_list_id
EndIf
EndIf
EndProcedure
Procedure JR_Current_element(JR_list_id.l) ; retourne l'adresse de l'element courant
ProcedureReturn PeekL(JR_list_id + 12)
EndProcedure
Procedure JR_Set_element(JR_list_id.l, *donne.l, offset.l, taille) ; offset est le decalage de copy (à utilser avec precaution) , taille est la taille des donne a copier (mettre 0 pour taille de la liste)
; permet de définir la valeur de l'element courant à partir d'une variable quelconque
; (pas d'un résultat direct)
; faire attention avec les variables structurées, toute la structure est nécessaire
element = PeekL(JR_list_id + 12)
If element
If taille
CopyMemory(*donne, element + 8 + offset, taille)
Else
CopyMemory(*donne, element + 8 + offset, PeekL(JR_list_id + 16))
EndIf
ProcedureReturn JR_list_id
EndIf
EndProcedure
Procedure JR_Get_element(JR_list_id.l, *variable.l) ; copie les données en mémoire dans la variable (de la bonne structure !!!!) d'adresse *variable
element = PeekL(JR_list_id + 12)
If element
CopyMemory(element + 8, *variable, PeekL(JR_list_id + 16))
ProcedureReturn JR_list_id
EndIf
EndProcedure
Procedure JR_Delete_element(JR_list_id.l, toujour_un_element.l = 0) ; efface l'élement courant et place l'element précedant en courant
element = PeekL(JR_list_id + 12)
If element
previous_element = PeekL(element)
next_element = PeekL(element + 4)
If previous_element
PokeL(previous_element + 4, next_element)
PokeL(JR_list_id + 12, previous_element)
ElseIf toujour_un_element
PokeL(JR_list_id + 12, next_element)
PokeL(JR_list_id + 4, Next_element)
Else
PokeL(JR_list_id + 4, Next_element)
EndIf
If next_element
PokeL(next_element, previous_element)
Else
PokeL(JR_list_id + 8, previous_element)
EndIf
PokeL(JR_list_id, PeekL(JR_list_id) - 1)
FreeMemory(element)
EndIf
EndProcedure
Procedure JR_Delete_linkedlist(JR_list_id.l) ; Efface la liste et libère les ressources en mémoire
last_element = PeekL(JR_list_id + 8)
If last_element
Repeat
previous_element = PeekL(last_element)
FreeMemory(last_element)
last_element = previous_element
Until previous_element
EndIf
FreeMemory(JR_list_id)
EndProcedure
Procedure JR_Reset_linkedlist(JR_list_id.l) ; place l'element courant avant le premier element de la liste
PokeL(JR_list_id + 12, 0)
EndProcedure
Procedure JR_Change_Current_element(JR_list_id.l, *adresse_element.l) ; l'élement courant deviens celui pointé par *adresse_element
PokeL(JR_list_id + 12, *adresse_element)
EndProcedure
Procedure JR_Count_element(JR_list_id.l) ; retourne le nombre d'element de la list
ProcedureReturn PeekL(JR_list_id)
EndProcedure
Procedure JR_Swap_element(JR_list_id, num1.l, num2.l) ; échange deux elements
nb_elem = PeekL(JR_list_id)
If num1 = num2 Or num1 > nb_elem Or num1 < 1 Or num2 > nb_elem Or num2 < 1 : ProcedureReturn 0 : EndIf
element1 = JR_Select_element(JR_list_id, num1, 1)
p1 = PeekL(element1)
n1 = PeekL(element1 + 4)
element2 = JR_Select_element(JR_list_id, num2, 1)
p2 = PeekL(element2)
n2 = PeekL(element2 + 4)
If num1 - num2 = 1
If num2 > 1
PokeL(p2 + 4, element1)
EndIf
PokeL(element1, p2)
PokeL(element1 + 4, element2)
PokeL(element2, element1)
PokeL(element2 + 4, n1)
If num1 < nb_elem
PokeL(n1, element2)
EndIf
ElseIf num2 - num1 = 1
If num1 > 1
PokeL(p1 + 4, element2)
EndIf
PokeL(element2, p1)
PokeL(element2 + 4, element1)
PokeL(element1, element2)
PokeL(element1 + 4, n2)
If num2 < nb_elem
PokeL(n2, element1)
EndIf
Else
If num1 > 1
PokeL(p1 + 4, element2)
EndIf
If num1 < nb_elem
PokeL(n1, element2)
EndIf
PokeL(element2, p1)
PokeL(element2 + 4, n1)
PokeL(element1, p2)
PokeL(element1 + 4, n2)
If num2 > 1
PokeL(p2 + 4, element1)
EndIf
If num2 < nb_elem
PokeL(n2, element1)
EndIf
EndIf
If num1 = 1
PokeL(JR_list_id + 4, element2)
EndIf
If num2 = 1
PokeL(JR_list_id + 4, element1)
EndIf
If num1 = nb_elem
PokeL(JR_list_id + 8, element2)
EndIf
If num2 = nb_elem
PokeL(JR_list_id + 8, element1)
EndIf
ProcedureReturn JR_list_id
EndProcedure
Procedure JR_Move_element(JR_list_id, num1.l, nouvelle_position.l); deplace un element
nb_elem = PeekL(JR_list_id)
If num1 = nouvelle_position Or num1 > nb_elem Or num1 < 1 Or nouvelle_position > nb_elem Or nouvelle_position < 1 : ProcedureReturn 0 : EndIf
element1 = JR_Select_element(JR_list_id, num1, 1)
p1 = PeekL(element1)
n1 = PeekL(element1 + 4)
element2 = JR_Select_element(JR_list_id, nouvelle_position, 1)
p2 = PeekL(element2)
n2 = PeekL(element2 + 4)
If num1 < nouvelle_position
PokeL(element1, element2)
PokeL(element1 + 4, n2)
If num1 > 1
PokeL(p1 + 4, n1)
EndIf
If num1 < nb_elem
PokeL(n1, p1)
EndIf
PokeL(element2 + 4, element1)
PokeL(n2, element1)
Else
PokeL(element1, p2)
PokeL(element1 + 4, element2)
If num1 > 1
PokeL(p1 + 4, n1)
EndIf
If num1 < nb_elem
PokeL(n1, p1)
EndIf
PokeL(element2, element1)
PokeL(p2 + 4, element1)
EndIf
ProcedureReturn JR_list_id
EndProcedure
Procedure JR_Copy_Linkelist(JR_list_id.l)
new = JR_Create_linkedlist(PeekL(JR_list_id + 16))
If new
nb = JR_Count_element(JR_list_id)
ad = PeekL(JR_list_id + 4)
For a = 1 To nb
JR_Add_element(new)
JR_Set_element(new, ad + 8, 0, 0)
ad = PeekL(ad + 4)
Next
EndIf
ProcedureReturn new
EndProcedure
; Procedure Jr_Sort_Linkedlist(JR_list_id.l, mode.l, OffsetDuChamp.l, type.l)
;
; For i = 2 To JR_Count_element(JR_list_id)
;
; elem = 0
;
; CopyMemory(PeekL(JR_list_id + 16) + 8 + OffsetDuChamp, @elem, len)
;
; JR_Reset_linkedlist(liste_1)
;
; b.point\x = 0
;
; While JR_Next_element(liste_1)
; JR_Get_element(liste_1, @b)
;
;
; Wend
;
; Next
;
; EndProcedure
;}
;{ ## test de démonstration
; liste_1 = JR_Create_linkedlist(SizeOf(point))
;
; Debug "adresse de la liste = " + Str(liste_1)
; Debug "nb element = " + Str(JR_Count_element(liste_1))
; Debug "## création de 10 elements"
;
; For a = 1 To 10
; JR_Add_element(liste_1)
;
; e.POINT\y = Random(55)
; e\x = a
;
; JR_Set_element(liste_1, @e, 0, 0)
; Next
;
; Debug "nb element = " + Str(JR_Count_element(liste_1))
; Debug "## elements :"
;
; JR_Reset_linkedlist(liste_1)
;
; b.point\x = 0
;
; While JR_Next_element(liste_1)
; JR_Get_element(liste_1, @b)
;
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
;
; Wend
;
; Debug "## selection de l'element 9"
;
; JR_Select_element(liste_1, 9, 0)
;
; JR_Get_element(liste_1, @b)
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
;
; Debug "## effacement de l'element courant (9)"
;
; JR_Delete_element(liste_1, 1)
;
; Debug "nb element = " + Str(JR_Count_element(liste_1))
;
; JR_Reset_linkedlist(liste_1)
;
; While JR_Next_element(liste_1)
; JR_Get_element(liste_1, @b)
;
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
; Wend
;
; Debug "## Echange des elements 1 et 3"
;
; JR_Swap_element(liste_1, 1, 3)
;
; JR_Reset_linkedlist(liste_1)
;
; While JR_Next_element(liste_1)
; JR_Get_element(liste_1, @b)
;
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
; Wend
;
; Debug "## deplacement de l'element 5 en 2eme position"
;
; JR_Move_element(liste_1, 5, 2)
;
; Debug "# test avec les elements suivants"
; JR_Reset_linkedlist(liste_1)
;
; While JR_Next_element(liste_1)
; JR_Get_element(liste_1, @b)
;
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
; Wend
;
; Debug "# test avec les elements precedents"
;
; JR_Select_element(liste_1, JR_Count_element(liste_1), 0)
;
; Repeat
; JR_Get_element(liste_1, @b)
;
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
;
;
; Until JR_Previous_element(liste_1) = 0
;
; Debug "### Effacement de la liste et creation d'une nouvelle"
;
; JR_Delete_linkedlist(liste_1)
;
; liste_1 = JR_Create_linkedlist(SizeOf(point))
;
; Debug "adresse de la liste = " + Str(liste_1)
; Debug "nb element = " + Str(JR_Count_element(liste_1))
; Debug "## création de 10 elements"
;
; For a = 1 To 10
; JR_Add_element(liste_1)
;
; e.POINT\y = Random(55)
; e\x = a
;
; JR_Set_element(liste_1, @e, 0, 0)
; Next
;
; Debug "nb element = " + Str(JR_Count_element(liste_1))
; Debug "## elements :"
;
; JR_Reset_linkedlist(liste_1)
;
; b.point\x = 0
;
; While JR_Next_element(liste_1)
; JR_Get_element(liste_1, @b)
;
; Debug "element x : " + Str(b\x) + " y : " + Str(b\y)
;
; Wend
;
; Debug "## changement de l'element 4 \ y"
;
; JR_Select_element(liste_1, 4, 0)
;
; JR_Get_element(liste_1, @b)
;
; Debug "element 4 : x : " + Str(b\x) + " y : " + Str(b\y)
;
; newdonne.l = 55
;
; JR_Set_element(liste_1, @newdonne, OffsetOf(POINT\y), SizeOf(Long))
;
; Debug "nouvelle valeur :"
;
; JR_Get_element(liste_1, @b)
;
; Debug "element 4 : x : " + Str(b\x) + " y : " + Str(b\y)
;}
2ème include : sur les courbes de bezier, c'est celui ci qu'il faut regarder
Code : Tout sélectionner
;{ include des dépendances
; IncludeFile "MODULE_JR_linkedlist.pbi"
;}
;{ Courbes de Béziers ( permet de créer et manipuler des courbes de bézier )
; ## module dépendance : JR_list
Structure Bezier_Point_d
x.d
y.d
EndStructure
Structure quad_point
x.d
y.d
vect_x.d
vect_y.d
EndStructure
Structure Bezier
P.Bezier_Point_d[4]
EndStructure
Procedure Bezier_Create(level.l, boucle.l) ; level defini le niveau de lissage de la courbe (5 est un level preferable, mettre plus affecte les performances), retourne l'id de la courbe de bézier créée
ad = AllocateMemory(12)
PokeL(ad, JR_Create_linkedlist(SizeOf(quad_point)))
PokeL(ad + 4, level)
PokeL(ad + 8, boucle)
ProcedureReturn ad
EndProcedure
Procedure Bezier_Add_Part(Bezier_id.l, x.d, y.d, vect_x.d, vect_y.d)
ad_list = PeekL(Bezier_id)
JR_Add_element(ad_list)
point.quad_point\x = x
point\y = y
point\vect_x = vect_x
point\vect_y = vect_y
JR_Set_element(ad_list, @point, 0, 0)
EndProcedure
Procedure Bezier_Delete_Part(Bezier_id.l, num.l)
ad_list = PeekL(Bezier_id)
JR_Select_element(ad_list, num, 0)
JR_Delete_element(ad_list, 0)
EndProcedure
Procedure RecursiveBezier(*b.Bezier, level.l, color)
Define.Bezier left, right
If level <= 0
;Dessine un segment
LineXY(*b\P[0]\x + 0.5, *b\P[0]\y + 0.5, *b\P[3]\x + 0.5, *b\P[3]\y + 0.5, color)
; Circle(*b\P[0]\x + 0.5, *b\P[0]\y + 0.5, 5, color)
; Circle(*b\P[3]\x + 0.5, *b\P[3]\y + 0.5, 5, color)
Else
;subdivide into 2 Bezier segments
left\P[0]\x = *b\P[0]\x
left\P[0]\y = *b\P[0]\y
left\P[1]\x = (*b\P[0]\x + *b\P[1]\x) / 2
left\P[1]\y = (*b\P[0]\y + *b\P[1]\y) / 2
left\P[2]\x = (*b\P[0]\x + 2**b\P[1]\x + *b\P[2]\x) / 4
left\P[2]\y = (*b\P[0]\y + 2**b\P[1]\y + *b\P[2]\y) / 4
left\P[3]\x = (*b\P[0]\x + 3**b\P[1]\x + 3**b\P[2]\x + *b\P[3]\x) / 8
left\P[3]\y = (*b\P[0]\y + 3**b\P[1]\y + 3**b\P[2]\y + *b\P[3]\y) / 8
;DrawBezierBase(@left,0,255,0);
right\P[0]\x = left\P[3]\x;
right\P[0]\y = left\P[3]\y;
right\P[1]\x = (*b\P[1]\x + 2**b\P[2]\x + *b\P[3]\x) / 4
right\P[1]\y = (*b\P[1]\y + 2**b\P[2]\y + *b\P[3]\y) / 4
right\P[2]\x = (*b\P[2]\x + *b\P[3]\x) / 2
right\P[2]\y = (*b\P[2]\y + *b\P[3]\y) / 2
right\P[3]\x = *b\P[3]\x
right\P[3]\y = *b\P[3]\y
;DrawBezierBase(@right,0,0,255)
;draw the 2 segments recursively
RecursiveBezier(@left,level -1, color)
RecursiveBezier(@right,level -1, color)
EndIf
EndProcedure
Procedure Bezier_Draw(Bezier_id.l, color.l, base.l)
Define inter.quad_point
ad_list = PeekL(Bezier_id)
nb = JR_Count_element(ad_list)
JR_Reset_linkedlist(ad_list)
JR_Next_element(ad_list)
JR_Get_element(ad_list, @inter)
For a = 1 To nb - 1
b.Bezier\P[0]\x = inter\x
b.Bezier\P[0]\y = inter\y
If a = 1
b.Bezier\P[1]\x = inter\x + inter\vect_x
b.Bezier\P[1]\y = inter\y + inter\vect_y
Else
b.Bezier\P[1]\x = inter\x - inter\vect_x
b.Bezier\P[1]\y = inter\y - inter\vect_y
EndIf
If base
Circle(inter\x, inter\y, 3, color)
Circle(b\P[1]\x, b\P[1]\y, 3, color)
LineXY(inter\x, inter\y, b\P[1]\x, b\P[1]\y, color)
EndIf
JR_Next_element(ad_list)
JR_Get_element(ad_list, @inter)
b.Bezier\P[3]\x = inter\x
b.Bezier\P[3]\y = inter\y
b.Bezier\P[2]\x = inter\x + inter\vect_x
b.Bezier\P[2]\y = inter\y + inter\vect_y
If base = 0
RecursiveBezier(@b, PeekL(Bezier_id + 4), color)
Else
Circle(inter\x, inter\y, 3, color)
Circle(b\P[2]\x, b\P[2]\y, 3, color)
Line(inter\x, inter\y, inter\vect_x, inter\vect_y, color)
EndIf
Next
If PeekL(Bezier_id + 8)
b.Bezier\P[2]\x = inter\x - inter\vect_x
b.Bezier\P[2]\y = inter\y - inter\vect_y
JR_Reset_linkedlist(ad_list)
JR_Next_element(ad_list)
JR_Get_element(ad_list, @inter)
b.Bezier\P[0]\x = inter\x
b.Bezier\P[0]\y = inter\y
b.Bezier\P[1]\x = inter\x - inter\vect_x
b.Bezier\P[1]\y = inter\y - inter\vect_y
If base = 0
RecursiveBezier(@b, PeekL(Bezier_id + 4), color)
Else
Circle(b\P[0]\x, b\P[0]\y, 3, color)
Circle(b\P[1]\x, b\P[1]\y, 3, color)
LineXY(b\P[0]\x, b\P[0]\y, b\P[1]\x, b\P[1]\y, color)
Circle(b\P[3]\x, b\P[3]\y, 3, color)
Circle(b\P[2]\x, b\P[2]\y, 3, color)
LineXY(b\P[3]\x, b\P[3]\y, b\P[2]\x, b\P[2]\y, color)
EndIf
EndIf
EndProcedure
Procedure Bezier_Move_Part(Bezier_id.l, num.l, x.d, y.d, vect_x.d, vect_y.d, option) ; option = 0 : tout les param sont changés, option = 1 : seuls x/y changent, option = 2 : seuls vects changent
ad_list = PeekL(Bezier_id)
JR_Select_element(ad_list, num, 0)
If option = 0
point.quad_point\x = x
point\y = y
point\vect_x = vect_x
point\vect_y = vect_y
JR_Set_element(ad_list, @point, 0, 0)
ElseIf option = 1
JR_Set_element(ad_list, @x, OffsetOf(quad_point\x), SizeOf(Double))
JR_Set_element(ad_list, @y, OffsetOf(quad_point\y), SizeOf(Double))
ElseIf option = 2
JR_Set_element(ad_list, @vect_x, OffsetOf(quad_point\vect_x), SizeOf(Double))
JR_Set_element(ad_list, @vect_y, OffsetOf(quad_point\vect_y), SizeOf(Double))
EndIf
EndProcedure
Procedure Bezier_Get_Part(Bezier_id.l, num.l, *quad_point)
ad_list = PeekL(Bezier_id)
JR_Select_element(ad_list, num, 0)
JR_Get_element(ad_list, *quad_point)
EndProcedure
Procedure Bezier_Reset_Part(Bezier_id.l) ; fonctionne avec Bezier_Move_Next_Part() et Bezier_Get_Next_Part()
ad_list = PeekL(Bezier_id)
JR_Reset_linkedlist(ad_list)
EndProcedure
Procedure Bezier_Move_Next_Part(Bezier_id.l, x.d, y.d, vect_x.d, vect_y.d, option) ; option = 0 : tout les param sont changés, option = 1 : seuls x/y changent, option = 2 : seuls vects changent
ad_list = PeekL(Bezier_id)
JR_Next_element(ad_list)
If option = 0
point.quad_point\x = x
point\y = y
point\vect_x = vect_x
point\vect_y = vect_y
JR_Set_element(ad_list, @point, 0, 0)
ElseIf option = 1
JR_Set_element(ad_list, @x, OffsetOf(quad_point\x), SizeOf(Double))
JR_Set_element(ad_list, @y, OffsetOf(quad_point\y), SizeOf(Double))
ElseIf option = 2
JR_Set_element(ad_list, @vect_x, OffsetOf(quad_point\vect_x), SizeOf(Double))
JR_Set_element(ad_list, @vect_y, OffsetOf(quad_point\vect_y), SizeOf(Double))
EndIf
EndProcedure
Procedure Bezier_Get_Next_Part(Bezier_id.l, *quad_point)
ad_list = PeekL(Bezier_id)
JR_Next_element(ad_list)
JR_Get_element(ad_list, *quad_point)
EndProcedure
Procedure Bezier_Move_Current_Part(Bezier_id.l, x.d, y.d, vect_x.d, vect_y.d, option) ; option = 0 : tout les param sont changés, option = 1 : seuls x/y changent, option = 2 : seuls vects changent
ad_list = PeekL(Bezier_id)
If option = 0
point.quad_point\x = x
point\y = y
point\vect_x = vect_x
point\vect_y = vect_y
JR_Set_element(ad_list, @point, 0, 0)
ElseIf option = 1
JR_Set_element(ad_list, @x, OffsetOf(quad_point\x), SizeOf(Double))
JR_Set_element(ad_list, @y, OffsetOf(quad_point\y), SizeOf(Double))
ElseIf option = 2
JR_Set_element(ad_list, @vect_x, OffsetOf(quad_point\vect_x), SizeOf(Double))
JR_Set_element(ad_list, @vect_y, OffsetOf(quad_point\vect_y), SizeOf(Double))
EndIf
EndProcedure
Procedure Bezier_Get_Current_Part(Bezier_id.l, *quad_point)
ad_list = PeekL(Bezier_id)
JR_Get_element(ad_list, *quad_point)
EndProcedure
Procedure Bezier_CountPart(Bezier_id.l)
ProcedureReturn JR_Count_element(PeekL(Bezier_id))
EndProcedure
Procedure Bezier_Free(Bezier_id.l)
JR_Delete_linkedlist(PeekL(Bezier_id))
FreeMemory(Bezier_id)
EndProcedure
Procedure Bezier_Set_Level(Bezier_id.l, level.l) ; change le niveau de lissage de la courbe
PokeL(Bezier_id + 4, level)
EndProcedure
Procedure Bezier_Get_Level(Bezier_id.l) ; retourne le niveau de lissage de la courbe
ProcedureReturn PeekL(Bezier_id + 4)
EndProcedure
Procedure Bezier_Set_Boucle(Bezier_id.l, boucle.l) ; change l'activation de la boucle
PokeL(Bezier_id + 8, boucle)
EndProcedure
Procedure Bezier_Get_Boucle(Bezier_id.l) ; retourne si l'option boucle est activé ou non
ProcedureReturn PeekL(Bezier_id + 8)
EndProcedure
Procedure Bezier_Copy(Bezier_id.l) ; duplique la courbe
ad = AllocateMemory(12)
PokeL(ad, JR_Copy_Linkelist(PeekL(Bezier_id)))
CopyMemory(Bezier_id + 4, ad + 4, 8)
; PokeL(ad + 4, PeekL(Bezier_id + 4))
; PokeL(ad + 8, PeekL(Bezier_id + 8))
ProcedureReturn ad
EndProcedure
Procedure Bezier_test_point(Bezier_id.l, sourie_x.l, sourie_y.l, sensibilite.l) ; renvoie l'adresse mémoire de 2 long qui donnent --> +0 : numéro de la partie de courbe | +4 : 1 si c'est le point, 2 si c'est le vecteur | +24 : si c'est un vect, 1 veux dire de prendre la symetrie , ne pas oublier de libérer la mémoire
Define inter.quad_point
*adresse = AllocateMemory(28)
ad_list = PeekL(Bezier_id)
nb = JR_Count_element(ad_list)
JR_Reset_linkedlist(ad_list)
For a = 1 To nb
JR_Next_element(ad_list)
JR_Get_element(ad_list, @inter)
b.Bezier\P[0]\x = inter\x
b.Bezier\P[0]\y = inter\y
b.Bezier\P[1]\x = inter\x + inter\vect_x
b.Bezier\P[1]\y = inter\y + inter\vect_y
b.Bezier\P[2]\x = inter\x - inter\vect_x
b.Bezier\P[2]\y = inter\y - inter\vect_y
dist.d = Sqr(Pow(b\P[0]\x - sourie_x, 2) + Pow(b\P[0]\y - sourie_y, 2))
If dist <= sensibilite
PokeL(*adresse, a)
PokeL(*adresse + 4, 1)
PokeL(*adresse + 8, b\P[0]\x)
PokeL(*adresse + 12, b\P[0]\y)
Break
EndIf
dist.d = Sqr(Pow(b\P[1]\x - sourie_x, 2) + Pow(b\P[1]\y - sourie_y, 2))
If dist <= sensibilite
PokeL(*adresse, a)
PokeL(*adresse + 4, 2)
PokeL(*adresse + 8, b\P[1]\x)
PokeL(*adresse + 12, b\P[1]\y)
PokeL(*adresse + 16, b\P[0]\x)
PokeL(*adresse + 20, b\P[0]\y)
Break
EndIf
dist.d = Sqr(Pow(b\P[2]\x - sourie_x, 2) + Pow(b\P[2]\y - sourie_y, 2))
If dist <= sensibilite
PokeL(*adresse, a)
PokeL(*adresse + 4, 2)
PokeL(*adresse + 8, b\P[2]\x)
PokeL(*adresse + 12, b\P[2]\y)
PokeL(*adresse + 16, b\P[0]\x)
PokeL(*adresse + 20, b\P[0]\y)
PokeL(*adresse + 24, 1)
Break
EndIf
Next
ProcedureReturn *adresse
EndProcedure
;}
;{ ## test de démonstration
;
; If OpenWindow(0, 0, 0, 800, 600, "Test des courbes de bézier", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
; CanvasGadget(0, 0, 0, 800, 600, #PB_Canvas_Keyboard)
;
; AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)
; EndIf
;
; ; on crée la courbe
; ma_bezier = Bezier_Create(5, #False)
;
; x0 = -1
; y0 = -1
;
; Repeat
; event = WaitWindowEvent()
;
; If event = #PB_Event_Gadget And EventGadget() = 0
; x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
; y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
;
; Select EventType()
; Case #PB_EventType_LeftClick
; If x0 = -1
; x0 = x
; y0 = y
; Else
; Bezier_Add_Part(ma_bezier, x, y, -(x - x0) / 2, -(y - y0) / 2)
;
; x0 = x
; y0 = y
; EndIf
;
; EndSelect
;
; EndIf
;
; ;{ dessin
;
; If StartDrawing(CanvasOutput(0))
; Box(0, 0, 800, 600, #Black)
;
; ; souris
; Circle(x, y, 2, #Red)
;
; ; dessin de la courbe
; Bezier_Draw(ma_bezier, #Green, #False)
;
; StopDrawing()
; EndIf
;
; ;}
;
; Until event = #PB_Event_CloseWindow
;
; End
;
;
;}
code de test pour montrer un résultat graphique :
Code : Tout sélectionner
InitSprite()
InitKeyboard()
OpenScreen(1280, 1024, 32, "Bezier")
IncludeFile "Librairie Sources\MODULE_JR_linkedlist.pbi"
IncludeFile "Librairie Sources\MODULE_Bezier_Courbes.pbi"
bezier = Bezier_Create(5, 1)
#nb = 6
nb1.d = 60
col = #Green
red.d = Red(col)
green.d = Green(col)
blue.d = Blue(col)
Structure listedepoint
P.POINT[#nb]
EndStructure
Define az.listedepoint, acc.listedepoint, time.listedepoint
size = SizeOf(listedepoint)
For a = 0 To #nb - 1
az\P[a]\x = Random(1280 - 100) + 50
az\P[a]\y = Random(1024 - 100) + 50
Next
NewList bezier.l()
For a = 0 To nb1
AddElement(bezier())
bezier() = Bezier_Create(5, 1)
Next
FirstElement(bezier())
For a = 0 To #nb - 1 Step 2
Bezier_Add_Part(bezier(), (az\P[a]\x + az\P[a + 1]\x) / 2, (az\P[a]\y + az\P[a + 1]\y) / 2, az\P[a]\x - (az\P[a]\x + az\P[a + 1]\x) / 2, az\P[a]\y - (az\P[a]\y + az\P[a + 1]\y) / 2)
Next
; aze = Bezier_Copy(
base = -1
it = -1
Repeat
it = -it
Delay(10)
ExamineKeyboard()
FirstElement(bezier())
If KeyboardReleased(#PB_Key_F1) : base = -base : EndIf
If KeyboardReleased(#PB_Key_Up) : Bezier_Set_Level(bezier(), Bezier_Get_Level(bezier()) + 1) : EndIf
If KeyboardReleased(#PB_Key_Down) : Bezier_Set_Level(bezier(), Bezier_Get_Level(bezier()) - 1) : EndIf
a = 0
ForEach bezier()
If a
da = ad
EndIf
ad = Bezier_Copy(bezier())
If a
Bezier_Free(bezier())
bezier() = da
EndIf
a + 1
Next
FirstElement(bezier())
b = 1
For a = 0 To #nb - 1
b = -b
If time\P[a]\x <= 0
time\P[a]\x = Random(80) + 50
acc\P[a]\x = Random(10) - 5
acc\P[a]\y = Random(10) - 5
Else
time\P[a]\x - 1
EndIf
az\P[a]\x + acc\P[a]\x
az\P[a]\y + acc\P[a]\y
If az\P[a]\x < 0 Or az\P[a]\x > 1280 : acc\P[a]\x = -acc\P[a]\x : EndIf
If az\P[a]\y < 0 Or az\P[a]\y > 1024 : acc\P[a]\y = -acc\P[a]\y : EndIf
If b = 1
Bezier_Move_Part(bezier(), a / 2 + 1, (az\P[a]\x + az\P[a - 1]\x) / 2, (az\P[a]\y + az\P[a - 1]\y) / 2, az\P[a - 1]\x - (az\P[a]\x + az\P[a - 1]\x) / 2, az\P[a - 1]\y - (az\P[a]\y + az\P[a - 1]\y) / 2, 0)
EndIf
Next
ClearScreen(0)
If StartDrawing(ScreenOutput())
j.d = 0
ForEach bezier()
j + 1
If (j/2 - Int(j/2) And it = 1) Or (j/2 - Int(j/2) = 0 And it = -1)
If j < nb1 / 2
color1.d = j / nb1
Else
color1.d = 1 - j / nb1
EndIf
Bezier_Draw(bezier(), RGB(red * color1, green * color1, blue * color1), 0)
If base = 1 : Bezier_Draw(bezier(), #Red, 1) : EndIf
EndIf
Next
StopDrawing()
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End