January 15, 2021, 05:42:36 PM

Author Topic: [bmx] Akima spline by Jur [ 1+ years ago ]  (Read 527 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Akima spline by Jur [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Akima spline
Author : Jur
Posted : 1+ years ago

Description : Make splines with akima interpolation method

Code :
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Graphics 800,600
  4. SeedRnd(MilliSecs())    'Different each time
  5. SetLineWidth(2)
  6.  
  7. Global SelectedPoint:Point
  8. Global Points:Point[10]
  9. MakePoints()
  10.  
  11. Function MakePoints()
  12.         For Local p:Int=0 Until Points.length
  13.                 Points[p]=New Point
  14.                 Points[p].x=Rand(50,750)
  15.                 Points[p].y=Rand(100,550)
  16.         Next
  17. EndFunction
  18.  
  19. While Not KeyHit(KEY_ESCAPE)
  20.         Cls
  21.        
  22.         For Local p:Int=0 Until Points.length
  23.                 If Abs(MouseX()-Points[p].x)<4 And Abs(MouseY()-Points[p].y)<4 Then
  24.                         If MouseDown(1) Then
  25.                                 SelectedPoint = Points[p]
  26.                         EndIf
  27.                 EndIf  
  28.         Next
  29.        
  30.         If SelectedPoint Then
  31.                 SelectedPoint.x=MouseX()
  32.                 SelectedPoint.y=MouseY()
  33.                 If MouseDown(1) = False Then
  34.                         SelectedPoint = Null
  35.                         FlushMouse()
  36.                 EndIf
  37.         EndIf
  38.        
  39.         If KeyHit(KEY_SPACE) Then MakePoints()
  40.  
  41.         Local xAprev:Float, yAprev:Float, xCprev:Float, yCprev:Float
  42.         For Local i:Int=2 Until Points.length-3
  43.                 For Local mu:Float=0 To 1 Step 0.05
  44.                         'DebugStop()
  45.  
  46.                         Local xC:Float = CubicInterpolate(Points[i-1].x, Points[i].x, Points[i+1].x, Points[i+2].x, mu)
  47.                         Local yC:Float = CubicInterpolate(Points[i-1].y, Points[i].y, Points[i+1].y, Points[i+2].y, mu)
  48.                        
  49.                         Local yA:Float = AkimaInterpolate(Points[i-2].y, Points[i-1].y, Points[i].y, Points[i+1].y, Points[i+2].y, Points[i+3].y, mu)
  50.                         Local xA:Float = AkimaInterpolate(Points[i-2].x, Points[i-1].x, Points[i].x, Points[i+1].x, Points[i+2].x, Points[i+3].x, mu)
  51.  
  52.                         If xAprev=0 And yAprev=0 Then
  53.                                 xAprev = xA
  54.                                 yAprev = yA
  55.                         EndIf
  56.                         If xCprev=0 And yCprev=0 Then
  57.                                 xCprev = xC
  58.                                 yCprev = yC
  59.                         EndIf
  60.                        
  61.                         SetColor 220,220,200
  62.                         DrawLine xCprev,yCprev, xC,yC
  63.                        
  64.                         SetColor 255,200,0
  65.                         DrawLine xAprev,yAprev, xA,yA
  66.  
  67.                         xAprev = xA
  68.                         yAprev = yA
  69.                         xCprev = xC
  70.                         yCprev = yC
  71.  
  72.                 Next
  73.         Next
  74.        
  75.        
  76.         'points
  77.         SetColor 255,255,255
  78.         For Local i:Int=2 Until Points.length-3
  79.                 DrawOval(Points[i].x-2, Points[i].y-2, 4,4)
  80.                 DrawText i,Points[i].x+7,Points[i].y+7
  81.         Next
  82.        
  83.         SetColor 220,220,200
  84.         DrawText "cubic spline",10,10
  85.         SetColor 255,200,0
  86.         DrawText "akima spline",10,30
  87.         SetColor 200,200,200
  88.         DrawText "move points with mouse, make new points with <space> ",10,50
  89.        
  90.         Flip
  91. Wend
  92.  
  93.  
  94. ' akima interpolation requires 6 points
  95. ' interpolate between y3 And y4 at position mu (0..1)
  96. '----------------------------------------------------------------------------
  97. Function AkimaInterpolate:Float(y1:Float, y2:Float, y3:Float, y4:Float, y5:Float, y6:Float, mu:Float)
  98.  
  99.         Local num1:Float = Abs((y5-y4)- (y4-y3))*(y3-y2) + Abs((y3-y2) - (y2-y1))*(y4-y3)
  100.         Local den1:Float = Abs((y5-y4) - (y4-y3)) + Abs((y3-y2) - (y2-y1))
  101.        
  102.         Local num2:Float = Abs((y6-y5)- (y5-y4))*(y4-y3) + Abs((y4-y3) - (y3-y2))*(y5-y4)
  103.         Local den2:Float = Abs((y6-y5) - (y5-y4)) + Abs((y4-y3) - (y3-y2))
  104.        
  105.         Local t1:Float
  106.         If den1>0.00001 Then   '0
  107.                 t1=num1/den1
  108.         Else
  109.                 t1=0.0
  110.         EndIf
  111.        
  112.         Local t2:Float
  113.         If den2>0.00001 Then   '0
  114.                 t2=num2/den2
  115.         Else
  116.                 t2=0.0
  117.         EndIf
  118.        
  119.         Local C:Float = (3*(y4-y3) - 2*t1 - t2)
  120.         Local D:Float = (t1 + t2 - 2*(y4-y3))
  121.        
  122.         Return  y3 + (t1 + (C + D*mu)*mu)*mu
  123.  
  124. EndFunction
  125.  
  126.  
  127.  
  128.  
  129. 'interpolate between y1 and y2
  130. Function CubicInterpolate:Float(y0:Float, y1:Float, y2:Float, y3:Float, mu:Float)
  131.    Local a0#,a1#,a2#,a3#,mu2#
  132.  
  133.    mu2 = mu*mu
  134.    a0 = y3-y2-y0+y1
  135.    a1 = y0-y1-a0
  136.    a2 = y2-y0
  137.    a3 = y1
  138.    
  139.    Return a0*mu*mu2+a1*mu2+a2*mu+a3
  140. End Function
  141.  
  142. Type Point
  143.         Field x:Int
  144.         Field y:Int
  145.        
  146.         Function Create:point(x#,y#)
  147.                 Local p:point=New point
  148.                 p.x=x
  149.                 p.y=y
  150.                 Return p
  151.         End Function
  152. End Type


Comments :


TAS(Posted 1+ years ago)

 Interesting


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal