Artemis.Bezier : Bézierkurven n-ter Ordnung + kubische
Übersicht BlitzMax, BlitzMax NG Codearchiv & Module
ArtemisBetreff: Artemis.Bezier : Bézierkurven n-ter Ordnung + kubische |
Sa, Nov 25, 2006 18:18 Antworten mit Zitat |
|
---|---|---|
Da ich für mein Projekt Bézierkurven brauche, habe ich mir ein kleines Modul geschrieben, um kubische Bézierkurven (n=3) und allgemeine Bézierkurven n-ter Ordnung zu berechnen.
Edit [28.11, 21:00] So, habe das Modul umstrukturiert, umbenannt in Artemis.Bezier und Bézierpatches hinzugefügt. Der ganze Quell-Code: [AUSKLAPPEN] SuperStrict
Rem bbdoc: Bézier about: Enhält Berechnungen für Bézierkurven und Bézierpatches. EndRem Module Artemis.Bezier ModuleInfo "Version: 1.0" ModuleInfo "Author: Artemis" ModuleInfo "License: Public Domain" ModuleInfo "Modserver: BlitzHelp" ModuleInfo ":" ModuleInfo "History: 1.00 erste Version" Import Artemis.Point Import Artemis.Math Import Brl.LinkedList Rem bbdoc: Enthält Funktionen zur Berechnung einer dreidimensionalen, kubischen Bézierkurve. EndRem Type TBezier Rem bbdoc: Gibt eine Koordinate aufgrund vier gegebener Koordinaten und der Stelle t zurück. EndRem Function get:Float(p0:Float, p1:Float, p2:Float, p3:Float, t:Float) If (t < 0) Or (t > 1) Then Return Null Return p0*(1-t)^3 + 3*p1*t*(1-t)^2 + 3*p2*t^2*(1-t) + p3*t^3 EndFunction Rem bbdoc: Gibt die X-Koordinate aufgrund vier gegebener Punkte und der Stelle t zurück. EndRem Function getX:Float(p0:TPoint, p1:TPoint, p2:TPoint, p3:TPoint, t:Float) If (t < 0) Or (t > 1) Then Return Null Return p0.x*(1-t)^3 + 3*p1.x*t*(1-t)^2 + 3*p2.x*t^2*(1-t) + p3.x*t^3 EndFunction Rem bbdoc: Gibt die Y-Koordinate aufgrund vier gegebener Punkte und der Stelle t zurück. EndRem Function getY:Float(p0:TPoint, p1:TPoint, p2:TPoint, p3:TPoint, t:Float) If (t < 0) Or (t > 1) Then Return Null Return p0.y*(1-t)^3 + 3*p1.y*t*(1-t)^2 + 3*p2.y*t^2*(1-t) + p3.y*t^3 EndFunction Rem bbdoc: Gibt die Z-Koordinate aufgrund vier gegebener Punkte und der Stelle t zurück. EndRem Function getZ:Float(p0:TPoint, p1:TPoint, p2:TPoint, p3:TPoint, t:Float) If (t < 0) Or (t > 1) Then Return Null Return p0.z*(1-t)^3 + 3*p1.z*t*(1-t)^2 + 3*p2.z*t^2*(1-t) + p3.z*t^3 EndFunction Rem bbdoc: Gibt den Punkt aufgrund vier gegebener Punkte und der Stelle t zurück. EndRem Function getPoint:TPoint(p0:TPoint, p1:TPoint, p2:TPoint, p3:TPoint, t:Float) If (t < 0) Or (t > 1) Then Return Null Local x:Float Local y:Float Local z:Float x = p0.x*(1-t)^3 + 3*p1.x*t*(1-t)^2 + 3*p2.x*t^2*(1-t) + p3.x*t^3 y = p0.y*(1-t)^3 + 3*p1.y*t*(1-t)^2 + 3*p2.y*t^2*(1-t) + p3.y*t^3 z = p0.z*(1-t)^3 + 3*p1.z*t*(1-t)^2 + 3*p2.z*t^2*(1-t) + p3.z*t^3 Return TPoint.Create(x, y, z) EndFunction EndType Rem bbdoc: Enthält Funktionen zur Berechnung einer dreidimensionalen, Bézierkurve n-ter Ordnung. EndRem Type TBezierN Rem bbdoc: Gibt eine Koordinate aufgrund beliebiger gegebener Koordinaten und der Stelle t zurück. EndRem Function get:Float(points:Float[], t:Float) If (t < 0) Or (t > 1) Then Return Null Local n:Int = points.length-1 Local i:Int = 0 Local p:Float Local r:Float = 0 For p = EachIn points r :+ p * TMath.BernsteinPolynomial(i, n, t) i :+ 1 Next Return r EndFunction Rem bbdoc: Gibt die X-Koordinate aufgrund beliebiger gegebener Punkte und der Stelle t zurück. EndRem Function getX:Float(points:TPoint[], t:Float) If (t < 0) Or (t > 1) Then Return Null Local n:Int = points.length-1 Local i:Int = 0 Local p:TPoint Local x:Float = 0 For p = EachIn points x :+ p.x * TMath.BernsteinPolynomial(i, n, t) i :+ 1 Next Return x EndFunction Rem bbdoc: Gibt die Y-Koordinate aufgrund beliebiger gegebener Punkte und der Stelle t zurück. EndRem Function getY:Float(points:TPoint[], t:Float) If (t < 0) Or (t > 1) Then Return Null Local n:Int = points.length-1 Local i:Int = 0 Local p:TPoint Local y:Float = 0 For p = EachIn points y :+ p.y * TMath.BernsteinPolynomial(i, n, t) i :+ 1 Next Return y EndFunction Rem bbdoc: Gibt die Z-Koordinate aufgrund beliebiger gegebener Punkte und der Stelle t zurück. EndRem Function getZ:Float(points:TPoint[], t:Float) If (t < 0) Or (t > 1) Then Return Null Local n:Int = points.length-1 Local i:Int = 0 Local p:TPoint Local z:Float = 0 For p = EachIn points z :+ p.z * TMath.BernsteinPolynomial(i, n, t) i :+ 1 Next Return z EndFunction Rem bbdoc: Gibt den Punkt aufgrund beliebiger gegebener Punkte und der Stelle t zurück. EndRem Function getPoint:TPoint(points:TPoint[], t:Float) If (t < 0) Or (t > 1) Then Return Null Local n:Int = points.length-1 Local i:Int = 0 Local p:TPoint Local x:Float = 0 Local y:Float = 0 Local z:Float = 0 For p = EachIn points x :+ p.x * TMath.BernsteinPolynomial(i, n, t) y :+ p.y * TMath.BernsteinPolynomial(i, n, t) z :+ p.z * TMath.BernsteinPolynomial(i, n, t) i :+ 1 Next Return TPoint.Create(x, y, z) EndFunction EndType Rem bbdoc: Definiert eine kubische Bézierkurve. EndRem Type TBezierCurve Field p0:TPoint Field p1:TPoint Field p2:TPoint Field p3:TPoint Rem bbdoc: Gibt die X-Koordinate zurück. EndRem Method getX:Float(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezier.getX(self.p0, self.p1, self.p2, self.p3, t) EndMethod Rem bbdoc: Gibt die Y-Koordinate zurück. EndRem Method getY:Float(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezier.getY(self.p0, self.p1, self.p2, self.p3, t) EndMethod Rem bbdoc: Gibt die Z-Koordinate zurück. EndRem Method getZ:Float(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezier.getZ(self.p0, self.p1, self.p2, self.p3, t) EndMethod Rem bbdoc: Gibt den Punkt zurück. EndRem Method getPoint:TPoint(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezier.getPoint(self.p0, self.p1, self.p2, self.p3, t) EndMethod EndType Rem bbdoc: Definiert eine Bézierkurve n-ter Ordnung. EndRem Type TBezierCurveN Field points:TList = New TList Rem bbdoc: Fügt einen Punkt an das Ende der Kurve an EndRem Method add(x:Float, y:Float, z:Float=0) self.points.addLast(TPoint.Create(x, y, z)) EndMethod Rem bbdoc: Fügt einen Punkt an das Ende der Kurve an EndRem Method addPoint(p:TPoint) self.points.addLast(p) EndMethod Rem bbdoc: Gibt die X-Koordinate zurück. EndRem Method getX:Float(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezierN.getX(TPoint[](self.points.toArray()), t) EndMethod Rem bbdoc: Gibt die Y-Koordinate zurück. EndRem Method getY:Float(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezierN.getY(TPoint[](self.points.toArray()), t) EndMethod Rem bbdoc: Gibt die Z-Koordinate zurück. EndRem Method getZ:Float(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezierN.getZ(TPoint[](self.points.toArray()), t) EndMethod Rem bbdoc: Gibt den Punkt zurück. EndRem Method getPoint:TPoint(t:Float) If (t < 0) Or (t > 1) Then Return Null Return TBezierN.getPoint(TPoint[](self.points.toArray()), t) EndMethod EndType Rem bbdoc: Definiert einen Bézierpatch mit beliebig vielen Punkten. EndRem Type TBezierPatch Field size_u:Int Field size_v:Int Field points:TPoint[][] Rem bbdoc: Erstellt einen neuen Bézierpatch mit der Anzahl der Punkte für die u-Béziers (size_u) und für die v-Béziers (size_v). EndRem Function Create:TBezierPatch(size_u:Int, size_v:Int) If (size_u < 2) Or (size_v < 2) Then Return Null Local bezier_patch:TBezierPatch = New TBezierPatch Local loop:Int bezier_patch.size_u = size_u bezier_patch.size_v = size_v bezier_patch.points = New TPoint[][size_v] For loop = 0 To size_v-1 bezier_patch.points[loop] = New TPoint[size_u] Next Return bezier_patch EndFunction Rem bbdoc: Gibt den Punkt des Patchs aufgrund der Beiden Kurvenpositionen u und v an. EndRem Method getPoint:TPoint(u:Float, v:Float) If (u < 0) Or (u > 1) Then Return Null If (v < 0) Or (v > 1) Then Return Null Local bezier:TPoint[] = New TPoint[size_v] Local loop :Int For loop = 0 To self.size_v-1 bezier[loop] = TBezierN.getPoint(self.points[loop], u) Next Return TBezierN.getPoint(bezier, v) EndMethod EndType Und das TPoint-Modul: Code: [AUSKLAPPEN] SuperStrict
Rem bbdoc: Point about: Dieses Modul beinhaltet eine einfache Klasse, die einen Punkt definiert. EndRem Module Artemis.Point ModuleInfo "Version: 1.02" ModuleInfo "Author: Artemis" ModuleInfo "License: Public Domain" ModuleInfo "Modserver: BlitzHelp" ModuleInfo ":" ModuleInfo "History: 1.02" ModuleInfo "History: Changed: Removed all classes but TPoint which contains now a 3d float point." ModuleInfo "History: 1.01" ModuleInfo "History: Added: T3DPoint and T3DFloatPoint." ModuleInfo "History: 1.00 first Release" Rem bbdoc: Diese Klasse definiert einen Punkt. EndRem Type TPoint Rem bbdoc: Diese Variable enthält die X-Koordinate des Punktes. EndRem Field x:Float Rem bbdoc: Diese Variable enthält die Y-Koordinate des Punktes. EndRem Field y:Float Rem bbdoc: Diese Variable enthält die Z-Koordinate des Punktes. EndRem Field z:Float Rem bbdoc: Diese Funktion erstellt einen neuen Punkt mit den übergebenen Koordinaten. EndRem Function Create:TPoint(x:Float, y:Float, z:Float=0) Local point:TPoint = New TPoint point.x = x point.y = y point.z = z Return point EndFunction Method toString:String() Local x:String = self.x Local y:String = self.y Local z:String = self.z While x[x.length-1..] = "0" x = x[..x.length-1] Wend If x[x.length-1..] = "." Then x = x[..x.length-1] While y[y.length-1..] = "0" y = y[..y.length-1] Wend If y[y.length-1..] = "." Then y = y[..y.length-1] While z[z.length-1..] = "0" z = z[..z.length-1] Wend If z[z.length-1..] = "." Then z = z[..z.length-1] Return "TPoint(" + x + ", " + y + ", " + z + ")" EndMethod EndType |
||
- Zuletzt bearbeitet von Artemis am So, Aug 31, 2008 17:21, insgesamt 2-mal bearbeitet
Vertex |
Sa, Nov 25, 2006 19:52 Antworten mit Zitat |
|
---|---|---|
Ist ja ganz schön, aber warum muss man für jeden "Kleinmist" denn bitteschön ein Modul machen? Vorschlag zur Erweiterung: Bézier-Patches - Man gibt 8 x 3D Punkte an, und er berechnet daraus eine Oberfläche. Ist auch relativ einfach umzusetzen. Bei GetPoint brauchste dann die 2 Parameter U und V, die auch im Interval [0, 1] liegen.
mfg olli |
||
vertex.dreamfall.at | GitHub |
Artemis |
Mo, Nov 27, 2006 20:14 Antworten mit Zitat |
|
---|---|---|
Jo, Bézier-Patches kommen. Bin gerade dabei, das Modul umzustrukturieren und zu vereinfachen.
Aber 8-Punkte? Sind das nicht 16-Punkte, so wie hier: ? Mit 16 Punkten klingt das für mich ganz logisch, aber mit 8 Punkten? |
||
Vertex |
Mo, Nov 27, 2006 22:00 Antworten mit Zitat |
|
---|---|---|
Ja, 16, sorry | ||
vertex.dreamfall.at | GitHub |
Artemis |
Di, Nov 28, 2006 22:09 Antworten mit Zitat |
|
---|---|---|
Ok, Bézierpatches sind da. Sie sind außerdem nicht auf 4*4 beschränkt, sondern sind variabel.
Außerdem habe ich das Modul umstrukturiert und vereinfacht und vor allem das Modul Artemis.Point verinfacht. Habe eine Bézierpatch vorhin getestet und es klappte alles. |
||
Übersicht BlitzMax, BlitzMax NG Codearchiv & Module
Powered by phpBB © 2001 - 2006, phpBB Group