Spline/Bezier ?!

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

MVB

Betreff: Spline/Bezier ?!

BeitragDo, Jun 09, 2005 19:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi.
Folgendes Problem. Ich wollte einen Rennstreckeneditor programmieren. Man erstellt mehrere Punkte und diese werden dann durch ein Spline/Bezier zu einer Strecke verbunden. Das Problem ist, dass ich keine Ahnung von Bezier/Spline oder anderen Kurven habe. Ich habe natürlich auch schon im diesem Forum gesucht und auf blitzbasic.com. Aber ich finde immer nur Ansätze mit denen ich nichts anfangen kann, da ich sie meist nicht verstehe. Folgende Funktion ist von blitzbase.de:
Code: [AUSKLAPPEN]
;-------------------------------------------------------------------
;Zeichnet eine "CATMULL ROM SLINE". Dabei werden die Start- und
;Endpunkte berührt. Die Abweichung von der idealen Form ist minimal.
;Ideal zum Verbinden von Koordinatenketten mit einer Linie. Der
;Start- und Endpunkt einer Koordinatenkette müssen doppelt angegeben
;werden.
;
;x1 = Horizontale Ablenkkoordinate 1
;y1 = Vertikale   Ablenkkoordinate 1
;x2 = Horizontale Startkoordinate
;y2 = Vertikale   Startkoordinate
;x3 = Horizontale Endkoordinate
;y3 = Vertikale   Endkoordinate
;x4 = Horizontale Ablenkkoordinate 2
;y4 = Vertikale   Ablenkkoordinate 2
;-------------------------------------------------------------------
Function spline(x1,y1,x2,y2,x3,y3,x4,y4)
  For u#=0 To 1.05 Step .05
    u2#=u#*u#
    u3#=u#*u#*u#
    f1#=-0.5*u3#+1.0*u2#-0.5*u#
    f2#= 1.5*u3#-2.5*u2#+1.0
    f3#=-1.5*u3#+2.0*u2#+0.5*u#
    f4#= 0.5*u3#-0.5*u2#
    x=x1*f1#+x2*f2#+x3*f3#+x4*f4#
    y=y1*f1#+y2*f2#+y3*f3#+y4*f4#
    If u#>0 Then Line ax,ay,x,y
    ax=x
    ay=y
  Next
End Function

Nach der Beschreibung müsste es damit eigentlich funktionieren. Aber egal was ich versuche, er zeichnet mir immer nur zerschnittene, unfertige, falsche oder ähnliche Kurven.
Könnt ihr mir helfen?
Ansätze, Beispiele, Tipps, usw. bitte posten.
Danke!

EDIT: Hab grad nochmal etwas auf blitzbasic.com rumgesucht und bin auf folgendes gestoßen. http://www.blitzbasic.com/Comm...=racetrack
So in etwa hab ich mir den Streckeneditor vorgestellt.
aquamonit.de|BlitzMax|MaxGUI
 

walski

Ehemaliger Admin

BeitragFr, Jun 10, 2005 1:11
Antworten mit Zitat
Benutzer-Profile anzeigen
So, Bezier:

Also wie ich dem hier:
http://www.id.unizh.ch/publications/ps/bezier.html

entnehme lässt sich für die Kurve folgender Algorithmus verwenden:

X = (x1 * ( 1.0 - u ) ^ 3.0 ) + ( x2 * ( 3.0 * u ) * ( ( 1.0 - u ) ^ 2.0 ) ) + ( x3 * ( ( 3.0 * u^2 ) ) * ( 1.0 - u ) ) + ( x4 * ( u ^ 3.0 ) )
Y = (y1 * ( 1.0 - u ) ^ 3.0 ) + ( y2 * ( 3.0 *u ) * ( ( 1.0 - u ) ^ 2.0 ) ) + ( y3 * ( ( 3.0 * u^2 ) ) * ( 1.0 - u ) ) + ( y4 * ( u ^ 3.0 ) )

Dabei ist x1 der Start-, x2 und x3 jeweils ein Stütz- und x4 der Endpunkt.

u durchläuft alle Werte von 0 bis 1 und je feiner es dies tut, desto mehr Punkte enthält später die Bezier-Kurve.

Daraus lässt sich dies hier basteln:
BlitzBasic: [AUSKLAPPEN]

Graphics 800,600,32,2

; Startpunkt
x1 = 100
y1 = 200

; Erster Stützpunkt
x2 = 100
y2 = 100

; Zweiter Stützpunkt
x3 = 400
y3 = 100

; Endpunkt
x4 = 400
y4 = 200


While Not KeyDown(1)

If MouseHit(1) Then

x2 = MouseX()
y2 = MouseY()

EndIf

If MouseHit(2) Then

x3 = MouseX()
y3 = MouseY()

EndIf

If ox3 <> x3 Or oy3 <> y3 Or ox2 <> x2 Or oy2 <> y2 Then


Cls
Oval x1-3,y1-3,6,6,0


Oval x2-3,y2-3,6,6,0


Oval x3-3,y3-3,6,6,0


Oval x4-3,y4-3,6,6,0


; Bezier-Kurve zeichnen
u# = 0

While u <= 1

X = (x1 * ( 1.0 - u ) ^ 3.0 ) + ( x2 * ( 3.0 * u ) * ( ( 1.0 - u ) ^ 2.0 ) ) + ( x3 * ( ( 3.0 * u^2 ) ) * ( 1.0 - u ) ) + ( x4 * ( u ^ 3.0 ) )
Y = (y1 * ( 1.0 - u ) ^ 3.0 ) + ( y2 * ( 3.0 * u ) * ( ( 1.0 - u ) ^ 2.0 ) ) + ( y3 * ( ( 3.0 * u^2 ) ) * ( 1.0 - u ) ) + ( y4 * ( u ^ 3.0 ) )

Plot X,Y

; je weniger sich das u pro Schleifendurchlauf erhöht, desto feiner wird die Kurve
u = u + .001

Wend

ox3 = x3
oy3 = y3

ox2 = x2
oy2 = y2

EndIf

Wend


Ob dich das jetzt sooo viel weiter bringt weiß ich allerdings nicht, wenn du wirklich ein komplettes Polygon interpolieren willst solltest du einfach mal nach "interpolation" oder "lagrange" googlen, ist allerdings kein ganz unmathematisches Thema Wink

Hoffe hat trotzdem etwas geholfen.

walski
buh!

MVB

BeitragFr, Jun 10, 2005 15:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi.
Danke! Werde mal sehen was ich machen kann. Wink
aquamonit.de|BlitzMax|MaxGUI

MVB

BeitragFr, Jun 10, 2005 16:23
Antworten mit Zitat
Benutzer-Profile anzeigen
So hab jetzt die Lösung gefunden. Mit Hilfe der blitzbase Funktion.
Ist in Blitzmax.
Code: [AUSKLAPPEN]

Graphics 800,600,32,60

Global List:TList = CreateList()

Type Point
   Field X:Int
   Field Y:Int
   Method New()
      ListAddLast List,Self
   End Method
End Type

Local Q:Int[3,2]

Repeat
Cls

If KeyHit(1) Then
   Points:+1
   p:Point=New Point
   p.X=MouseX()
   p.Y=MouseY()
   
EndIf


Z=0
For p=EachIn List
   Z:+1
   SetColor 255,255,255
   If Z=2 Then SetColor 255,0,0
   DrawSpline(Q[0,0],Q[0,1],Q[1,0],Q[1,1],Q[2,0],Q[2,1],p.X,p.Y)
   
   Q[0,0]=Q[1,0]
   Q[0,1]=Q[1,1]
   Q[1,0]=Q[2,0]
   Q[1,1]=Q[2,1]
   Q[2,0]=p.X
   Q[2,1]=p.Y

Next

For p=EachIn List
   SetColor 0,0,255
   DrawOval p.X-3,p.Y-3,6,6
Next


FlushMem
Flip
Until KeyHit(KEY_ESCAPE)


Function DrawSpline(x1,y1,x2,y2,x3,y3,x4,y4)
  For u#=0 To 1.0005 Step .0005
    u2#=u#*u#
    u3#=u#*u#*u#
    f1#=-0.5*u3#+1.0*u2#-0.5*u#
    f2#= 1.5*u3#-2.5*u2#+1.0
    f3#=-1.5*u3#+2.0*u2#+0.5*u#
    f4#= 0.5*u3#-0.5*u2#
    x=x1*f1#+x2*f2#+x3*f3#+x4*f4#
    y=y1*f1#+y2*f2#+y3*f3#+y4*f4#
   If u#>0 Then DrawOval x-20,y-20,40,40
    ax=x
    ay=y
  Next
End Function


aquamonit.de|BlitzMax|MaxGUI

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group