March 05, 2021, 07:08:18 AM

Author Topic: [bb] Natural Cubic Spline by Sweenie [ 1+ years ago ]  (Read 476 times)

Offline BlitzBot

[bb] Natural Cubic Spline by Sweenie [ 1+ years ago ]
« on: June 29, 2017, 12:28:42 AM »
Title : Natural Cubic Spline
Author : Sweenie
Posted : 1+ years ago

Description : Cubic Spline

Code :
Code: BlitzBasic
  1. ; Natural Cubic Spline
  2. ; Based on a java-applet by Tim Lambert
  3. ;
  4. ; Drag the red dots around with the mouse
  5.  
  6. Graphics 800,600,0,2
  7. SetBuffer BackBuffer()
  8.  
  9. Type Cubic
  10.  Field a#
  11.  Field b#
  12.  Field c#
  13.  Field d#
  14. End Type
  15.  
  16. Const Points = 8 ; Number of points
  17. Const Steps = 24 ; Number of substeps between points (Higher number = Smoother curve = Slower drawing)
  18.  
  19. ;Arrays for calculations
  20. Const n=Points-1  
  21. Dim xp#(n)
  22. Dim yp#(n)
  23. Dim xc.Cubic(n)
  24. Dim yc.Cubic(n)
  25. Dim gamma#(n+1)
  26. Dim delta#(n+1)
  27. Dim D#(n+1)
  28.  
  29. ;Place the points
  30. For i=0 To n
  31.  xp#(i)=i*(GraphicsWidth()/Points+1)+((GraphicsWidth()/Points+1)/2)
  32.  yp#(i)=GraphicsHeight()/2
  33. Next
  34.  
  35. ;Init the CubicsArrays
  36. InitCubics()
  37.  
  38. CalcCubics()
  39. Cls
  40. DrawSpline()
  41. Flip
  42.  
  43. Dragging=False
  44.  
  45. While Not KeyHit(1)
  46.  
  47.  If MouseDown(1) And Dragging=False Then
  48.   mx=MouseX():my=MouseY()
  49.   For i=0 To n
  50.    px=xp(i):py=yp(i)
  51.    If mx>px-3 And mx<px+3 And my>py-3 And my<py+3 Then
  52.     DragPoint=i
  53.         Dragging=True
  54.     Exit
  55.    EndIf
  56.   Next
  57.  EndIf
  58.  
  59.  If MouseDown(1)=False And Dragging=True Then
  60.   Dragging=False
  61.  EndIf
  62.  
  63.  If Dragging Then
  64.   xp#(DragPoint)=MouseX()
  65.   yp#(DragPoint)=MouseY()
  66.   CalcCubics()
  67.   Cls
  68.   DrawSpline() 
  69.   Flip
  70.  EndIf
  71.  
  72. Wend
  73. End
  74.  
  75.  
  76. Function DrawSpline()
  77.  x#=CubicEval(xc(0),0.0)
  78.  y#=CubicEval(yc(0),0.0)
  79.  
  80.   Color 255,255,255
  81.  
  82. For i=0 To n-1
  83.  For j=1 To Steps
  84.   oldx#=x#
  85.   oldy#=y#
  86.   stp#=Float(j)/Float(Steps)
  87.   x#=CubicEval(xc(i),stp#)
  88.   y#=CubicEval(yc(i),stp#)
  89.   Line oldx#,oldy#,x#,y#
  90.  Next
  91. Next
  92.  
  93.   Color 255,0,0
  94.   For i=0 To n
  95.    Oval xp#(i)-3,yp#(i)-3,6,6,True
  96.   Next
  97. End Function
  98.  
  99.  
  100. Function CalcCubics()
  101.  
  102. gamma(0) = 1.0/2.0
  103. For i=1 To n-1
  104.  gamma(i) = 1/(4-gamma(i-1))
  105. Next
  106. gamma(n) = 1/(2-gamma(n-1))
  107.  
  108. ; First the X-points
  109.  
  110. delta(0) = 3*(xp(1)-xp(0))*gamma(0)
  111. For i=1 To n-1
  112.  delta(i) = (3*(xp(i+1)-xp(i-1))-delta(i-1))*gamma(i)
  113. Next
  114. delta(n)=(3*(xp(n)-xp(n-1))-delta(n-1))*gamma(n)
  115.  
  116. D(n)=delta(n)
  117. For i=n-1 To 0 Step -1
  118.  D(i) = delta(i) - gamma(i)*D(i+1)
  119. Next
  120.  
  121. For i=0 To n-1
  122.  xc(i)a# = xp(i)
  123.  xc(i)# = D(i)
  124.  xc(i)c# = 3 * (xp(i+1)-xp(i)) - 2*D(i) - D(i+1)
  125.  xc(i)d# = 2 * (xp(i)-xp(i+1)) + D(i) + D(i+1)
  126. Next
  127.  
  128. ; Then the Y-points
  129.  
  130. delta(0) = 3*(yp(1)-yp(0))*gamma(0)
  131. For i=1 To n-1
  132.  delta(i) = (3*(yp(i+1)-yp(i-1))-delta(i-1))*gamma(i)
  133. Next
  134. delta(n)=(3*(yp(n)-yp(n-1))-delta(n-1))*gamma(n)
  135.  
  136. D(n)=delta(n)
  137. For i=n-1 To 0 Step -1
  138.  D(i) = delta(i) - gamma(i)*D(i+1)
  139. Next
  140.  
  141. For i=0 To n-1
  142.  yc(i)a# = yp(i)
  143.  yc(i)# = D(i)
  144.  yc(i)c# = 3 * (yp(i+1)-yp(i)) - 2*D(i) - D(i+1)
  145.  yc(i)d# = 2 * (yp(i)-yp(i+1)) + D(i) + D(i+1)
  146. Next
  147.  
  148. End Function
  149.  
  150. Function CubicEval#(Cubic.Cubic,u#)
  151.  ta#=Cubica#
  152.  tb#=Cubic#
  153.  tc#=Cubicc#
  154.  td#=Cubicd#   
  155.  
  156.  Return (((td#*u#)+tc#)*u#+tb#)*u#+ta#
  157. End Function
  158.  
  159. Function InitCubics()
  160.  For i=0 To n
  161.   xc.Cubic(i) = New Cubic
  162.   yc.Cubic(i) = New Cubic
  163.  Next
  164. End Function


Comments :


Stevie G(Posted 1+ years ago)

 Superb, this is easily adapted into the makings of a simple track editor. I just added the following and it works a treat.
Code: [Select]
;Place the points
HGW = GraphicsWidth()*.5
HGH = GraphicsHeight()*.5
For i=0 To n
angle# = Float(  i ) / Float( n ) *360.0
xp(i) = HGW + Cos ( angle) * HGW*.75
yp(i) = HGH + Sin( angle ) * HGH *.75
Next



Jeroen(Posted 1+ years ago)

 Excellent! [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal