Seite 2 von 3

Verfasst: 20.09.2007 21:56
von Scarabol
@Stargate
Der Link sollte dir weiterhelfen.
http://www.arndt-bruenner.de/mathe/scri ... spline.htm

Ich find das hier das Thema super erklärt wurde, was mir leider nicht hilft da ich es trotzdem nicht verstehe.
Bis
Wegen di=yi ist die rechte Seite von (VI) für i>0 und i<n bekannt. Weil auch alle entsprechenden x bekannt sind, lassen sich die bi für 0<i<n mit einem linearen Gleichungssystem aus allen Gleichungen (VI) gewinnen.
is noch alles klar aber genau in diesem Satz stört mich am Ende das "(VI)". Wieso sagt er aus allen Gleichungen und schreibt dann (VI) dahinter?
Also ich denke es kann nur entweder "allen Gleichungen" oder (VI) sein....

Gruß
Scarabol

Verfasst: 20.09.2007 23:47
von kutta
Hier mal ein Spline Code aus dem Archiv von einem Dennis
hoffe er ist nicht sauer wenn ichs poste. Ich hab kein Plan wie es funktioniert. Vielleicht hilfts euch weiter.
Punkte setzen mit linkem Mausclick und dann Enter drücken.


Code: Alles auswählen

 #SUBDIVS=10 
Structure Point2D 
x.w 
y.w 
EndStructure 

;---------Interpolating Splines----------- 

Procedure AbsLNG(a.l) 
  If a >> 31 
    a * -1 
  EndIf 
  ProcedureReturn a 
EndProcedure 


Procedure Mod(a, b) 
  Erg.l = a - a / b * b 
  If a >> 31 : Erg + AbsLNG(b) : EndIf 
  ProcedureReturn Erg 
EndProcedure 

Procedure.w InterpolateSpline (tTime.f,tpx1.f,tpy1.f,tpx2.f,tpy2.f,tpx3.f,tpy3.f,tpx4.f,tpy4.f) 
  
  Shared Final.Point2D 
  tTime2.f = tTime * tTime 
  tTime3.f = tTime2 * tTime 
  
  ;-------------------------------------------------- 
  tpOneX=  (-tpx1 + 3 * tpx2 - 3 * tpx3 + tpx4) * tTime3 
  tpOneY=  (-tpy1 + 3 * tpy2 - 3 * tpy3 + tpy4) * tTime3 
  
  ;-------------------------------------------------- 
  tpTwoX=  (2 * tpx1 - 5 * tpx2 + 4 * tpx3 - tpx4) * tTime2 
  tpTwoY=  (2 * tpy1 - 5 * tpy2 + 4 * tpy3 - tpy4) * tTime2 
  
  ;-------------------------------------------------- 
  tpThreeX=(-tpx1 + tpx3) * tTime 
  tpThreeY=(-tpy1 + tpy3) * tTime 
  
  ;-------------------------------------------------- 
  tpFourX= (2 * tpx2) 
  tpFourY= (2 * tpy2) 
  ;================================================== 
  
  Final\x=(tpOneX+tpTwoX+tpThreeX+tpFourX)/2 
  Final\y=(tpOneY+tpTwoY+tpThreeY+tpFourY)/2 
  
  ;-------------------------------------------------- 
    
EndProcedure 



InitSprite() 
InitKeyboard() 
InitMouse() 

If OpenScreen(800,600,16,"Cuttmull-Rom-Splines") 
    
   NewList PointList.Point2D() 
   CreateSprite(0,10,10) 
    
   StartDrawing(SpriteOutput(0)) 
    Circle(5,5,5,RGB(255,155,155)) 
   StopDrawing() 
    
    
   Repeat 
    ExamineKeyboard() 
    If ExamineMouse() 
      xm=MouseX() 
      ym=MouseY() 
      If MouseButton(1)<>0 
        AddElement(PointList()) 
        PointList()\x=xm 
        PointList()\y=ym 
      EndIf 
    EndIf 
    
   Repeat 
    ExamineMouse() 
   Until MouseButton(1)=0 
   FlipBuffers() 
   ClearScreen(RGB(0,0,0)) 
   StartDrawing(ScreenOutput()) 
    DrawingMode(1) 
    FrontColor(RGB(255,255,255)) 
   
   StopDrawing() 
   c=CountList(PointList()) 
   FirstElement(PointList()) 
   For n=1 To c 
     StartDrawing(ScreenOutput()) 
     
      Circle(PointList()\x,PointList()\y,5,RGB(255,0,0)) 
     StopDrawing() 
     NextElement(PointList()) 
   Next 
    
   DisplaySprite(0,xm-5,ym-5) 
        
   Until KeyboardPushed(#PB_Key_All) 
   If C>1 
   FirstElement(PointList()) 
   Dim p.Point2D(100) 
    
   For n=1 To C 
    
   p(n)\x=PointList()\x 
   p(n)\y=PointList()\y 
   NextElement(PointList()) 
   Next  
    
   For n=1 To C 
    t0 = mod((n - 2 + C) , C + 1) 
    t1 =  n 
    t2 = Mod(n, C) + 1 
    t3 = mod((n + 1),C) + 1 
    
    For m=1 To #SUBDIVS 
      Time.f=(m-1.0)/#SUBDIVS 
    InterpolateSpline(Time,p(t0)\x,p(t0)\y,p(t1)\x,p(t1)\y,p(t2)\x,p(t2)\y,p(t3)\x,p(t3)\y) 
    StartDrawing(ScreenOutput()) 
     Plot(Final\x,Final\y,RGB(255,255,255)) 
    StopDrawing() 
    Next 
   Next 
    
   StartDrawing(ScreenOutput()) 

    
   StopDrawing() 
   FlipBuffers() 
   Repeat 
   ExamineKeyboard() 
   Until KeyboardPushed(#PB_Key_Escape) 
   EndIf 

EndIf

hier nochmal der Link
http://www.purebasic.fr/german/archive/ ... a4e3e557c9

Verfasst: 21.09.2007 06:48
von Scarabol
Super danke der Code funzt, optimiere ihn nochmal und setzt ihn dann heut mittag hier rein...
Brauchst dir keine Sorgen machen, hast ja daraufhin verwiesen, dass es nicht dein Code ist dann ist meistens alles in Butter...

Bis dann
Scarabol

Verfasst: 21.09.2007 10:55
von Kaeru Gaman
Code, der bereits veröffentlicht und freigegeben wurde,
kann bedenkenlos wieder gepostet werden.

natürlich würde es als böses foul gewertet werden,
wenn man fremden code als seinen eigenen bezeichnet.
du hast einwandfrei auf den ursprünglichen Autor verwiesen,
also ist alles in Ordnung.

Verfasst: 21.09.2007 14:58
von Scarabol
Irgendwie funktioniert die Interpolation in dem Code aber nicht richtig, die sieht irgendwie merkwürdig aus, eben nicht wie eine vernünftige Funktion...

[Edit]
Vielleicht kann ja noch jemand was zu meinem ersten Post auf dieser Seite sagen...
[/Edit]

Gruß
Scarabol

Verfasst: 21.09.2007 16:55
von Spirit
Man könnte doch einfach die Hermite-Interpolation nutzen. Dafür teilt man
das Spline in einzelne Segmente, ein Segment wird durch jeweils zwei
Control-Points begrenzt. Für jedes Segment kann man nun eine Funktion
dritten Grades berechnen, die zwischen zwei Punkten interpoliert.

Die sieht dann so aus:

f(x) = (2*p1 - 2*p2 + t1 + t2) * x^3 + (3*p2 - 3*p1 - 2*t1 - t2) * x² + t1 * x + p1

p1 = f(0) - entspricht der y-Koordinate des linken Control-Points
p2 = f(1) - entspricht der y-Koordinate des rechten Control-Points
t1 : Anstieg der Tangente in p1
t2 : Anstieg der Tangente in p2

Den entsprechenden y-Wert bekommt man dann raus, indem man den
x-Wert (der zwischen 0 und 1 liegen muss) in die Gleichung einsetzt.
Der Verlauf des Splines hängt von den eingesetzten Werten für die
Tangenten ab. Das einfachste wäre wahrscheinlich, die Tangente auf
den nächtsen Control-Point auszurichten, also:

t[n] = (y[n+1] - y[n]) / (x[n+1] - x[n])

wobei t[n] die Tangente des n-ten Control-Points ist und x und y die
Koordinaten der Punkte.

Ein entsprechende Prozedur müsste dann für eine angebene Position
auf dem Spline zunächst das entsprechende Segment finden, den
x-Wert dann so skalieren, dass er zwischen 0 und 1 liegt und diesen
dann in die obere Gleichung einsetzen.

Verfasst: 21.09.2007 17:54
von Scarabol
Hi Spirit,

", dass er zwischen 0 und 1 liegt und diesen dann in die obere Gleichung einsetzen."

Denke mal du meinst zwischen den x Werten des 0ten und 1sten Punktes, oder?

Gruß
Scarabol

Verfasst: 21.09.2007 20:27
von Scarabol
Hab hier mal nen Code geschrieben, der das umsetzt was Spirit oben beschreibt, aber irgendwie kommen viel zu hohe Werte dabei raus.
Währ super wenn mal einer nen Blick draufwerfen kann, ich glaub das es nur ein Tipfehler ist aber ich find ihn nicht...

Gruß
Scarabol

Code: Alles auswählen

; f(x) = (2*p1 - 2*p2 + t1 + t2) * x^3 + (3*p2 - 3*p1 - 2*t1 - t2) * x² + t1 * x + p1
; 
; p1 = f(0) - entspricht der y-Koordinate des linken Control-Points
; p2 = f(1) - entspricht der y-Koordinate des rechten Control-Points
; t1 : Anstieg der Tangente in p1 = (y2 - y1) / (x2 - x1)
; t2 : Anstieg der Tangente in p2 = (y3 - y2) / (x3 - x2)
; t[n] = (y[n+1] - y[n]) / (x[n+1] - x[n])

Macro AddPnt()
  AddElement(Pnt())
  Read Pnt()\x
  Read Pnt()\y
EndMacro

Macro t(n)
  (PntAr(n+1)\y-PntAr(n)\y)/(PntAr(n+1)\x-PntAr(n)\x)
EndMacro

Macro f(x)
  (2*PntAr(Int(x))\y - 2*PntAr(Int(x)+1)\y + t(Int(x)) + t(Int(x)+1)) * Pow(x,3) + (3*PntAr(Int(x)+1)\y - 3*PntAr(Int(x))\y - 2*PntAr(Int(x))\y - t(Int(x)+1)) * x*x + t(Int(x)) * x + PntAr(Int(x))
EndMacro

NewList Pnt.Point()

DataSection
  TerrainData:
  Data.l 0, 100, 1, 103, 2, 106, 3, 112, 4, 116, 5, 119, 6, 121, 7, 121, 8, 122, 9, 124, 10, 123, 11, 119, 12, 117, 13, 120, 14, 123, 15, 125, 16, 123, 17, 115, 18, 109, 19, 104, 20, 99, 21, 95, 22, 92, 23, 89, 24, 87, 25, 85, 26, 83, 27, 80, 28, 77, 29, 77, 30, 74, 31, 69, 32, 65, 33, 66, 34, 69, 35, 74, 36, 79, 37, 82, 38, 83, 39, 83, 40, 85, 41, 91, 42, 96, 43, 101, 44, 106, 45, 107, 46, 106, 47, 106, 48, 106, 49, 107, 50, 108, 51, 109, 52, 111, 53, 111, 54, 110, 55, 110, 56, 111, 57, 110, 58, 111, 59, 113, 60, 116, 61, 118, 62, 118, 63, 118, 64, 120, 65, 122, 66, 122, 67, 123, 68, 122, 69, 118, 70, 114, 71, 111, 72, 108, 73, 105, 74, 100, 75, 94, 76, 89, 77, 86, 78, 85, 79, 83, 80, 81, 81, 78, 82, 74, 83, 70, 84, 66, 85, 63, 86, 58, 87, 52, 88, 48, 89, 44, 90, 41, 91, 39, 92, 36, 93, 33, 94, 30, 95, 27, 96, 24, 97, 24, 98, 25, 99, 28, 100, 30, 101, 34, 102, 38, 103, 42, 104, 45, 105, 48, 106, 50, 107, 52, 108, 52, 109, 50, 110, 48, 111, 50, 112, 51, 113, 52, 114, 53, 115, 55, 116, 56, 117, 57, 118, 59, 119, 59, 120, 58, 121, 56, 122, 55, 123, 53, 124, 51, 125, 48, 126, 46, 127, 46, 128, 48, 129, 50, 130, 51, 131, 50, 132, 49, 133, 52, 134, 55, 135, 58, 136, 60, 137, 59, 138, 57, 139, 56, 140, 55, 141, 55, 142, 55, 143, 53, 144, 51, 145, 50, 146, 50, 147, 50, 148, 50, 149, 49, 150, 47, 151, 44, 152, 43, 153, 41, 154, 39, 155, 38, 156, 37, 157, 36, 158, 34, 159, 32, 160, 32, 161, 32, 162, 32, 163, 31, 164, 29, 165, 30, 166, 32, 167, 33, 168, 33, 169, 32, 170, 32, 171, 34, 172, 35, 173, 35, 174, 32, 175, 29, 176, 26, 177, 23, 178, 19, 179, 15, 180, 12, 181, 9, 182, 7, 183, 5, 184, 3, 185, 2, 186, 1, 187, 0, 188, 0, 189, 0, 190, 0, 191, 0, 192, 0, 193, 0, 194, 0, 195, 0, 196, 0, 197, 0, 198, 0, 199, 0, 200, 0, 201, 0, 202, 0, 203, 2, 204, 5, 205, 7, 206, 7, 207, 7, 208, 7, 209, 8, 210, 9, 211, 9, 212, 10, 213, 11, 214, 12, 215, 15, 216, 19, 217, 24, 218, 30, 219, 40, 220, 49, 221, 59, 222, 68, 223, 76, 224, 81, 225, 87, 226, 92, 227, 97, 228, 102, 229, 109, 230, 115, 231, 119, 232, 121, 233, 122, 234, 119, 235, 119, 236, 123, 237, 125, 238, 124, 239, 123, 240, 124, 241, 123, 242, 120, 243, 114, 244, 107, 245, 101, 246, 98, 247, 97, 248, 96, 249, 95, 250, 98, 251, 102, 252, 104, 253, 103, 254, 102, 255, 102, 256, 101
EndDataSection

Restore TerrainData
For i = 0 To 256
  AddPnt()
Next

c = CountList(Pnt())

Dim PntAr.Point(c)

ForEach Pnt()
  PntAr(ListIndex(Pnt()))\x = Pnt()\x
  PntAr(ListIndex(Pnt()))\y = Pnt()\y
Next

Debug t(0)

Debug f(0)

Verfasst: 21.09.2007 21:47
von Scarabol
Hi Leute,

der Code funzt!!!!

:allright: :allright:

Code: Alles auswählen

; f(x) = (2*p1 - 2*p2 + t1 + t2) * x^3 + (3*p2 - 3*p1 - 2*t1 - t2) * x² + t1 * x + p1
; 
; p1 = f(0) - entspricht der y-Koordinate des linken Control-Points
; p2 = f(1) - entspricht der y-Koordinate des rechten Control-Points
; t1 : Anstieg der Tangente in p1 = (y2 - y1) / (x2 - x1)
; t2 : Anstieg der Tangente in p2 = (y3 - y2) / (x3 - x2)
; t[n] = (y[n+1] - y[n]) / (x[n+1] - x[n])

Define.f in

Macro AddPnt()
  AddElement(Pnt())
  Read Pnt()\x
  Read Pnt()\y
EndMacro

Macro t(n)
  (PntAr(n+1)\y-PntAr(n)\y)/(PntAr(n+1)\x-PntAr(n)\x)
EndMacro

Macro f(x)
  in = x-Int(x)
  p1 = PntAr(Int(x))\y
  p2 = PntAr(Int(x)+1)\y
  t1 = t(Int(x)) : Debug t1
  t2 = t(Int(x)+1) : Debug t2
  Debug ((2*p1 - 2*p2 + t1 + t2) * Pow(in,3) + (3*p2 - 3*p1 - 2*t1 - t2) * Pow(in,2) + t1 * in + p1)
EndMacro

NewList Pnt.Point()

DataSection
  TerrainData:
  Data.l 0, 100, 1, 103, 2, 106, 3, 112, 4, 116, 5, 119, 6, 121, 7, 121, 8, 122, 9, 124, 10, 123, 11, 119, 12, 117, 13, 120, 14, 123, 15, 125, 16, 123, 17, 115, 18, 109, 19, 104, 20, 99, 21, 95, 22, 92, 23, 89, 24, 87, 25, 85, 26, 83, 27, 80, 28, 77, 29, 77, 30, 74, 31, 69, 32, 65, 33, 66, 34, 69, 35, 74, 36, 79, 37, 82, 38, 83, 39, 83, 40, 85, 41, 91, 42, 96, 43, 101, 44, 106, 45, 107, 46, 106, 47, 106, 48, 106, 49, 107, 50, 108, 51, 109, 52, 111, 53, 111, 54, 110, 55, 110, 56, 111, 57, 110, 58, 111, 59, 113, 60, 116, 61, 118, 62, 118, 63, 118, 64, 120, 65, 122, 66, 122, 67, 123, 68, 122, 69, 118, 70, 114, 71, 111, 72, 108, 73, 105, 74, 100, 75, 94, 76, 89, 77, 86, 78, 85, 79, 83, 80, 81, 81, 78, 82, 74, 83, 70, 84, 66, 85, 63, 86, 58, 87, 52, 88, 48, 89, 44, 90, 41, 91, 39, 92, 36, 93, 33, 94, 30, 95, 27, 96, 24, 97, 24, 98, 25, 99, 28, 100, 30, 101, 34, 102, 38, 103, 42, 104, 45, 105, 48, 106, 50, 107, 52, 108, 52, 109, 50, 110, 48, 111, 50, 112, 51, 113, 52, 114, 53, 115, 55, 116, 56, 117, 57, 118, 59, 119, 59, 120, 58, 121, 56, 122, 55, 123, 53, 124, 51, 125, 48, 126, 46, 127, 46, 128, 48, 129, 50, 130, 51, 131, 50, 132, 49, 133, 52, 134, 55, 135, 58, 136, 60, 137, 59, 138, 57, 139, 56, 140, 55, 141, 55, 142, 55, 143, 53, 144, 51, 145, 50, 146, 50, 147, 50, 148, 50, 149, 49, 150, 47, 151, 44, 152, 43, 153, 41, 154, 39, 155, 38, 156, 37, 157, 36, 158, 34, 159, 32, 160, 32, 161, 32, 162, 32, 163, 31, 164, 29, 165, 30, 166, 32, 167, 33, 168, 33, 169, 32, 170, 32, 171, 34, 172, 35, 173, 35, 174, 32, 175, 29, 176, 26, 177, 23, 178, 19, 179, 15, 180, 12, 181, 9, 182, 7, 183, 5, 184, 3, 185, 2, 186, 1, 187, 0, 188, 0, 189, 0, 190, 0, 191, 0, 192, 0, 193, 0, 194, 0, 195, 0, 196, 0, 197, 0, 198, 0, 199, 0, 200, 0, 201, 0, 202, 0, 203, 2, 204, 5, 205, 7, 206, 7, 207, 7, 208, 7, 209, 8, 210, 9, 211, 9, 212, 10, 213, 11, 214, 12, 215, 15, 216, 19, 217, 24, 218, 30, 219, 40, 220, 49, 221, 59, 222, 68, 223, 76, 224, 81, 225, 87, 226, 92, 227, 97, 228, 102, 229, 109, 230, 115, 231, 119, 232, 121, 233, 122, 234, 119, 235, 119, 236, 123, 237, 125, 238, 124, 239, 123, 240, 124, 241, 123, 242, 120, 243, 114, 244, 107, 245, 101, 246, 98, 247, 97, 248, 96, 249, 95, 250, 98, 251, 102, 252, 104, 253, 103, 254, 102, 255, 102, 256, 101
EndDataSection

Restore TerrainData
For i = 0 To 256
  AddPnt()
Next

c = CountList(Pnt())

Dim PntAr.Point(c)

ForEach Pnt()
  PntAr(ListIndex(Pnt()))\x = Pnt()\x
  PntAr(ListIndex(Pnt()))\y = Pnt()\y
Next

f(2)

Verfasst: 21.09.2007 22:32
von Scarabol
So jetzt die Masterfrage:
Lässt sich die Interpolation auch als f(x,z) (Funktion von x und z, also 3D) bestimmen?

Gruß
Scarabol