Posted: 7th Nov 2002 20:34
Hey all. If you've been scratching your head over the mysterious CATMULLROM VECTOR commands, this might provide some assistance to you.

This is the 2D version of the tutorial. If well accepted, I'll port it over to 3 dimentional splines to be used with camera movement.

Hope this helps ease the pain of the documentation! ;o)

+ Code Snippet
` ------------------------------------------------------------
` Catmull-Rom Spline Manipulation & Demonstration
` ------------------------------------------------------------
`                         Author: ChipOne (aka James Chambers)
`                                      Date: Novemeber 7, 2002
` ------------------------------------------------------------
` An Explaination of Catmull-Rom Splines
` Catmull-Rom Splines (CS) are essentially a simplification of
` Hermite spline definition.  Instead of providing 2 points
` and their tangents (for weighting the direction of the
` curve), we can simply provide four points: two as anchors
` and two to 'bend' the curve.
`
` In DarkBasic Pro you can call a function to generate any
` point along the line between the two anchors.  The function
` CATMULLROM VECTOR2 is the 2D implementation of this function
` and works as follows:
`   CATMULLROM VECTOR2 VectorToStoreResult,
`                      BendVector1, AnchorVector1,
`                      AnchorVector2, BendVector2,
`                      PointPositionFloat
` Vector2's in DBP are simply variables that allow you to
` store both an X and Y value in them; therefore, the
` BendVectors and AnchorVectors all need to be set up prior
` to calling the funciton.
`
` The PointPositionFloat is a number between 0.0 and 100.0 to
` let the function know which point on the line you are
` looking to calculate, which is then stored in the
` VectorToStoreResult.
`
` An important note is that vectors are similar to objects and
` are created and referenced by number.  For more information
` see the MAKE VECTOR2 command in the help file.
`
` ------------------------------------------------------------

` ------------------------------------------------------------
` some basic setup
` ------------------------------------------------------------
sync on : sync rate 30
set text font "tahoma" : set text size 11 : set text to bold

` ------------------------------------------------------------
` constants and global variables
` ------------------------------------------------------------
#constant V2_BEND1 1
#constant V2_ANCHOR1 2
#constant V2_ANCHOR2 3
#constant V2_BEND2 4
#constant V2_RESULT 5

global curvector as integer

` ------------------------------------------------------------
` basic initialization
` ------------------------------------------------------------
curvector = 1
InitializeVectors()

` ------------------------------------------------------------
` our main game loop
` ------------------------------------------------------------
do
   cls

   ` check for user input
   getInput()

   ` do our output to the screen
   drawCutmullRomSpline()
   drawVectorPoints()

   ` draw text to screen
   drawText()

   sync
loop

end

` ------------------------------------------------------------
` function declarations
` ------------------------------------------------------------
   function InitializeVectors()
      ` create the vectors.  we're pretty sure that the creation
      ` will be successful, but we still have to stuff the return
      ` value of the call in a variable (result will always be 1)
      result = make vector2(V2_BEND1)
      result = make vector2(V2_ANCHOR1)
      result = make vector2(V2_ANCHOR2)
      result = make vector2(V2_BEND2)
      ` the last vector will be used for interpolation on the
      ` spline.  we won't need initial values for this.
      result = make vector2(V2_RESULT)

      ` plop some initial values into the vectors so we have
      ` something to draw to the screen
      set vector2 V2_BEND1, 100, 150
      set vector2 V2_ANCHOR1, 225, 200
      set vector2 V2_ANCHOR2, 350, 200
      set vector2 V2_BEND2, 500, 250

   endfunction

` ------------------------------------------------------------
   function getInput()
      ` test for switches to other vectors
      if inkey$() = "1" then curvector = V2_BEND1
      if inkey$() = "2" then curvector = V2_ANCHOR1
      if inkey$() = "3" then curvector = V2_ANCHOR2
      if inkey$() = "4" then curvector = V2_BEND2

      ` if the user is holding the mouse button down we have
      ` to update the x & y of the current vector
      if mouseclick()
         set vector2 curvector, mousex(), mousey()
      endif

   endfunction

` ------------------------------------------------------------
   function drawCutmullRomSpline()
      ` draw the line on the screen
      ink rgb(255,255,255), 0

      ` interate through 1000 points to make sure we get all
      ` pixels between the two points.  should be easy on a
      ` 640x480 screen with 1000 interations.
      for i = 1 to 1000
         catmullrom vector2 V2_RESULT, V2_BEND1, V2_ANCHOR1, V2_ANCHOR2, V2_BEND2, 0.001*i
         dot x vector2(V2_RESULT), y vector2(V2_RESULT)
      next i

   endfunction

` ------------------------------------------------------------
   function drawVectorPoints()
      ` use a different colour to circle each of the vector
      ` points to show the user where they are
      ink rgb(0,0,255), 0 : circle x vector2(V2_BEND1), y vector2(V2_BEND1), 2
      ink rgb(255,0,0), 0 : circle x vector2(V2_ANCHOR1), y vector2(V2_ANCHOR1), 2
      ink rgb(0,255,0), 0 : circle x vector2(V2_ANCHOR2), y vector2(V2_ANCHOR2), 2
      ink rgb(128,128,128), 0 : circle x vector2(V2_BEND2), y vector2(V2_BEND2), 2

   endfunction

` ------------------------------------------------------------
   function drawText()
      ` draw out the names of the vectors
      ink rgb(255,255,255), 0
      center text x vector2(V2_BEND1), y vector2(V2_BEND1) - 15, "Bend Vector 1"
      center text x vector2(V2_ANCHOR1), y vector2(V2_ANCHOR1) - 15, "Anchor Vector 1"
      center text x vector2(V2_ANCHOR2), y vector2(V2_ANCHOR2) - 15, "Anchor Vector 2"
      center text x vector2(V2_BEND2), y vector2(V2_BEND2) - 15, "Bend Vector 2"

      ` title & instructions
      set text to bold
      center text screen width()/2, 5, "Catmull-Rom Spline Demonstration (by ChipOne)"
      set text to normal
      center text screen width()/2, screen height()-30, "Use keys 1, 2, 3 and 4 to select the current vector"
      center text screen width()/2, screen height()-15, "Click mouse to set new position"

   endfunction



Cheers,
ChipOne
Posted: 8th Nov 2002 1:13
This is really useful, thanks a lot . It's cleared up all of my 3dmaths problems, which were mainly (well, completely) to do with creating the vectors and matrices. Porting it into 3 dimensions would be really useful, I might have a go before you post the code. You could make some really good 20-liners with this I'm sure.