POV-Ray : Newsgroups : povray.binaries.scene-files : Making functions for natural cubic splines : Re: Making functions for natural cubic splines Server Time
30 Apr 2024 23:11:15 EDT (-0400)
  Re: Making functions for natural cubic splines  
From: Bald Eagle
Date: 13 Oct 2014 12:35:00
Message: <web.543bfe1a5b2bbe7b5e7df57c0@news.povray.org>
"Nevado" <MYPUBLICNAME(a)sol.dk> wrote:

> I'll try and see if my high-school math is enough to handle Tor's code.

I didn't even try to follow the math - I just did a quick verbatim literal
translation from the c++ based SDL to JustBasic

See if you can plug some of this in where it needs to go.
I popped some comments in there and did the best I could on short notice, but I
figured that you "get" JustBASIC enough to know what to do with functions and
subroutines.  See what I tried to do in the SplineDraw.bas file in that respect.

I haven't tested this or looked for typos, but I figured this would get you
started.

Size = 5;
N = Size - 1;


'This is the weird way I came up to populate an array from a list
dim Times (Size)
Times$ = "-2, -1, 0, 0.5, 1"
for i = 0 to N
 Times (i) = val (WORD$ (Times$, i , "," ))
next i


dim Points (Size, 3)
Points$ = "-2, 0, 40, 0, 0, -2, 1, 0, 2, 0, 6, 2, 8, 2, 2"
for i = 0 to N
 Points (i,1) = val (WORD$ (Points$, 1+i*3 , "," ))
 Points (i,2) = val (WORD$ (Points$, 2+i*3 , "," ))
 Points (i,3) = val (WORD$ (Points$, 3+i*3 , "," ))
next i


Start = Times[0]
End   = Times[N]
Span  = End - Start

'T.O.K.'s way, using global variables

dim X (Size)
dim Y (Size)
dim Z (Size)


for i = 0 to N
X (i) = Points (i, 1)
Y (i) = Points (i, 2)
Z (i) = Points (i, 3)
next i

dim tt (Size)
dim yy (Size)

dim hh (Size)
dim uu (Size)
dim vv (Size)
dim zz (Size)

dim kk (Size, 3)


'#macro CalculateCoefficients()
' Change this to a subroutine or a function and place at end of code
sub CalculateCoefficients hh, tt, kk, yy, uu, vv, zz

for i = 0 to N-1
 hh(i) = tt(i+1) - tt(i)
 kk (i, 1) = 6*(yy(i+1) - yy(i))/hh(i)
next i

for i = 2 to N-1
 uu(1) = 2*(hh(0) + hh(1))
 vv(1) = kk(1, 1) - kk(0, 1) - hh(i-1)*vv(i-1)/uu(i-1)
next i

zz(n) = 0
for i = n-1 to 1 step -1
 zz(i) = (vv(i) - hh(i)*zz(i+1)/uu(i)
next i
zz(0) = 0

for i = 0 to N-1
 kk(i,0) = (zz(i+1) - zz(i)/(6*hh(i))
 kk (i, 1) = zz(i)/2
 kk (i,2) = -hh(i)/6*zz(i+1) + 2*zz(i)) +(yy(i+1) - yy(i))/hh(i)
next i

end sub ' or end function


for i = 0 to N
 tt(i) = Times(i)
 yy(i) = X(i)
next i


// Calculate coefficients for the X polynomials
call CalculateCoefficients hh, tt, kk, yy, uu, vv, zz

dim Coeffs_X (Size, 3)
' // Copy kk to Coeffs_X
for i = 0 to N-1
 Coeffs_X (i, 0) = kk (i, 0)
 Coeffs_X (i, 1) = kk (i, 1)
 Coeffs_X (i, 2) = kk (i, 2)
next i


// Calculate coefficients for the Y polynomials

// Copy Y to yy
for i = 0 to N
 yy(i) = Y(i)
next i

call CalculateCoefficients hh, tt, kk, yy, uu, vv, zz


dim Coeffs_Y (Size, 3)

// Copy kk to Coeffs_Y
for i = 0 to N-1
 Coeffs_Y (i, 0) = kk (i, 0)
 Coeffs_Y (i, 1) = kk (i, 1)
 Coeffs_Y (i, 2) = kk (i, 2)
next i



// Calculate coefficients for the Z polynomials
// Copy Z to yy
for i = 0 to N
 yy(i) = Z(i)
next i

call CalculateCoefficients hh, tt, kk, yy, uu, vv, zz


dim Coeffs_Z (Size, 3)

// Copy kk to Coeffs_Y
for i = 0 to N-1
 Coeffs_Z (i, 0) = kk (i, 0)
 Coeffs_Z (i, 1) = kk (i, 1)
 Coeffs_Z (i, 2) = kk (i, 2)
next i



'#macro
function CubicPolynomial T, A, B, C, D

  (D + T*(C + T*(B + T*A))) // Equals (A*T^3 + B*T^2 + C*T + D)

'#end // macro CubicPolynomial
end function


'#macro
sub CalculateCoordinates T, I

 dT = T - Times(i)
     ComponentX = CubicPolynomial (dT, Coeffs_X (i, 0), Coeffs_X (i, 1),
Coeffs_X (i, 2), X (i))

 ComponentY = CubicPolynomial (dT, Coeffs_Y (i, 0), Coeffs_Y (i, 1), Coeffs_Y
(i, 2), Y (i))

 ComponentZ = CubicPolynomial (dT, Coeffs_Z (i, 0), Coeffs_Z (i, 1), Coeffs_Z
(i, 2), Z (i))

'#end // macro CalculateCoordinates
end sub

Color$ = "Cyan, Green, Orange, Yellow, Blue"
' I haven't yet gotten a firm grasp of BASIC graphics - Nevado appears to be
really familiar
' do a lookup using using the   WORD$( Color$, n , "," )   trick
' or convert this to an rgb value, etc.
'#declare Colors =
'  array[Size] {
'    color Cyan,
'    color Green,
'    color Orange,
'    color Yellow,
'    color Blue // Not used
'  }

Intervals = 400

Radius = 0.08

for J = 0 to Intervals - 1     'replaces T.O.K's while loop
 T = Start + J/Intervals*Span
 ComponentX = 0
 ComponentY = 0
 ComponentZ = 0

 if T < Times(0) then
  sub CalculateCoordinates T, 0
  '#declare Color = (Colors[0]/2 + White);
 end if

 for  i = 0 to N-1
  if Times(i) <= T & T < Times(i+1) then
  ' you may have to check the proper BASIC syntax for this comparison logic
  sub CalculateCoordinates T, i
  '#declare Color = Colors[I];
  end if
 next i

 if Times(n) <= T then
  sub CalculateCoordinates T, N-1
  '#declare Color = (Colors[N-1]/2 + White);
 end if

 #grid, "size 5 ; color "; WORD$( Color$, n , "," ) ;" ; set "; XandY(Points,
1); " "; XandY(Points, 2)
 ' sphere {<ComponentX, ComponentY, ComponentZ>, Radius pigment { color Color }}
next J


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.