Bézier-Kurven - Die Anfänge

Übersicht BlitzBasic FAQ und Tutorials

Neue Antwort erstellen

 

n-Halbleiter

Betreff: Bézier-Kurven - Die Anfänge

BeitragDi, Jul 14, 2009 19:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Guten Abend liebe BBP-Gemeinde!

Da sich versch. Fragen zu meinem Code über Bézierkurven im Codearchiv ergaben, möchte ich hier nun kurz erläutern, was Bézier-Kurven sind und wie man sie berechnet. Ich gehe hier von einem gewissen Grundwissen in Mathematik aus.

Vorwissen: parametrische Kurven:

Ich denke, jeder kennt Funktionen der Form f(x) = y = x². Sie beschreibt eine Parabel, hier die Normalparabel. Eine parametrische Kurve ist eine, bei der jede Koordinate durch eine einzelne Funktion berechnet wird. Um alles nun berechenbar zu halten, führen wir eine neue Variable ein, z.B. a. Unsere Kurve wird nun beschrieben durch die Funktionen X(a) und Y(a).

Beispiel:
X(a)= a * 2
Y(a)= a - 2

a = 1 | 2 | 3 | 4
X(a)= 2 | 4 | 6 | 8
Y(a)= -1| 0 | 1 | 2

Ich hoffe, das ist soweit klar

Bézier Kurven - Jetzt geht's los

1.: Linien
Eine Linie von Punkt A (XA|YA) nach B (XB|YB) lässt sich ebenfalls durch zwei Funktionen darstellen:

X(a) = XA * a + XB * (1 - a)
Y(a) = YA * a + YB * (1 - a)

a ist in diesen Funktionen quasi der Fortschritt. Im folgenden Text werde ich anstatt (1 - a) b schreiben, da es einfacher zu schreiben und zu lesen ist. Setzen wir a = 0,5 erhalten wir den Punkt zwischen unseren beiden Kontrollpunkten, bei a = 0,25 den Punkt auf einem viertel des Weges. Die ganze Prozedur ist quasi eine von a abhängige Gewichtung der Punkte A bzw. B.

2.: Quadratische Kurven:

Wie stellen wir nun Kurven dar?

Wir erinnern uns, Polynomfunktionen (z.B. f(x) = y = x²) beschreiben Kurven. Wie kriegen wir nun unsere Funktionen in eine Form, die uns Polynome liefert? Wir brauchen auf jeden Fall 3 Polynome, da wir drei Punkte für eine Kurve brauchen. (a + b) liefert uns keine Polynome... (a + b)² tut dies schon. Sehen wir uns nun die ausmultiplizierte Form an: a² + 2 * a * b + b². Setzen wir nun für a einen Wert zwischen 0 und 1 und für b 1-a ein, dann erhalten wir als Ergebnis immer 1. Genau wie bei der Linie.

Probieren wir nun aus, ob es funktioniert (wir brauchen zusätzlich noch einen Punkt C (CX|CY)):
X(a) = AX * a² + BX * a * b + CX * b²
Y(a) = AY * a² + BY * a * b + CY * b²

Ein Beispielcode hierzu:
Code: [AUSKLAPPEN]
Graphics 800,600,32,2
SetBuffer BackBuffer()
Dim PA(1),PB(1),PC(1)
Global timer=CreateTimer(60)
Local a#,C#,C2=0

Repeat
   If MouseHit(1)
      C2=C2+1
      Select C2
         Case 1
            PA(0)=MouseX():PA(1)=MouseY()
         Case 2
            PB(0)=MouseX():PB(1)=MouseY()
         Case 3
            PC(0)=MouseX():PC(1)=MouseY()
      End Select
   EndIf
   If C2=3 Then Exit
   Flip 0
   WaitTimer timer
   Cls
Forever

ClsColor 100,100,100

Repeat
   Color 0,200,0
   Line PA(0),PA(1),PB(0),PB(1)
   Line PB(0),PB(1),PC(0),PC(1)
   Color 200,0,0
   Rect PA(0)-1,PA(1)-1,2,2
   Rect PB(0)-1,PB(1)-1,2,2
   Rect PC(0)-1,PC(1)-1,2,2
   
   Color 200,200,0
   For C=0 To 1 Step 0.0005
      Plot X(C),Y(C)
   Next
   
   Color 0,0,255
   Rect X(1-a)-1,Y(1-a)-1,2,2,1
   ;Plot X(a),Y(a)
   
   a=a+0.005
   
   If a>=1 Then a=0
   
   Color 255,255,255
   Text 10,10,a
   
   Flip 0
   WaitTimer timer
   Cls
Until KeyHit(1)
End

Function X#(a#)
   Local b#=1-a
   Return ((PA(0)*a*a)+(PB(0)*2*a*b)+(PC(0)*b*b))
End Function

Function Y#(a#)
   Local b#=1-a
   Return ((PA(1)*a*a)+(PB(1)*2*a*b)+(PC(1)*b*b))
End Function
(Nicht gerade sehr elegant, aber funktionell)

Diese Form nennt sich quadratisch wegen dem "²" in "(a + b)²".

3.: Kubische Kurven ( Rolling Eyes ):

Der nächste Schritt sind nun Kurven mit vier Punkten, dem Start-, dem Endpunkt und zwei Kontrollpunkte. Was machen wir? Es ist an sich einfach zu erraten, wir sehen uns die Formel (a + b)³ an. Ausmultipliziert ist das a³ + 3 * a² * b + 3 * a * b² + b³. Hier können wir nun auch jedes Polynom mit der Koordinate des zugehörigen Punktes multiplizieren. Ich spare mir die Formeln, da sie leicht herzuleiten sein dürften, sondern schreibe direkt einen Code: [AUSKLAPPEN]
Graphics 800,600,32,2
AppTitle "Spline-Spielwiese"
SetBuffer BackBuffer()
Dim PA(1),PB(1),PC(1),PD(1)
Global timer=CreateTimer(60)
Local a#,C#,C2=0

Repeat
   If MouseHit(1)
      C2=C2+1
      Select C2
         Case 1
            PA(0)=MouseX():PA(1)=MouseY()
         Case 2
            PB(0)=MouseX():PB(1)=MouseY()
         Case 3
            PC(0)=MouseX():PC(1)=MouseY()
         Case 4
            PD(0)=MouseX():PD(1)=MouseY()
      End Select
   EndIf
   If C2=4 Then Exit
   Flip 0
   WaitTimer timer
   Cls
Forever

ClsColor 100,100,100

Repeat
   Color 0,200,0
   Line PA(0),PA(1),PB(0),PB(1)
   Line PC(0),PC(1),PD(0),PD(1)
   Color 200,0,0
   Rect PA(0)-1,PA(1)-1,2,2,1
   Rect PB(0)-1,PB(1)-1,2,2,1
   Rect PC(0)-1,PC(1)-1,2,2,1
   Rect PD(0)-1,PD(1)-1,2,2,1
   
   Color 200,200,0
   For C=0 To 1 Step 0.0005
      Plot X(C),Y(C)
   Next
   
   Color 0,0,255
   Rect X(1-a)-1,Y(1-a)-1,2,2,1
   ;Plot X(a),Y(a)
   
   a=a+0.005
   
   If a>=1 Then a=0
   
   Color 255,255,255
   Text 10,10,a
   
   Flip 0
   WaitTimer timer
   Cls
Until KeyHit(1)
End

Function X#(a#)
   Local b#=1-a,t=0
   Return (PA(t)*a*a*a+PB(t)*3*a*a*b+PC(t)*3*a*b*b+PD(t)*b*b*b)
End Function

Function Y#(a#)
   Local b#=1-a,t=1
   Return (PA(t)*a*a*a+PB(t)*3*a*a*b+PC(t)*3*a*b*b+PD(t)*b*b*b)
End Function


Dieses Schema lässt sich nun für jeden weiteren Grad weiterführen, wen das noch interessiert, kann sich meinen Codearchiv-Eintrag zum Thema ansehen (Link oben).
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit
Ploing!
Blog

"Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935)

Neue Antwort erstellen


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group