Interpolation mit PB?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
kutta
Beiträge: 40
Registriert: 04.07.2005 09:48

Beitrag 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
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Spirit
Beiträge: 174
Registriert: 13.04.2005 19:09

Beitrag 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.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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)
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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)
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag 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
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Antworten