TGC Codebase Backup



Using Catmull Rom Splines by Hamish McHaggis

19th Apr 2004 10:48
Summary

This is a demontration of how to use vector2 commands to create a smooth curve between 2D points, using catmull rom splines.



Description

This is a demontration of how to use vector2 commands to create a smooth curve between 2D points, using catmull rom splines. Catmull rom splines use 4 control points, but by stringing lots together you can get a long smooth curve between points.

The same can be done with vector3, just use 3D coords not 2D ones.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    `2D Catmull Rom Splines in DBPro
`By Joseph Thomson
`18/04/04

randomize timer()

set display mode 800,600,32

type pointType
	x as integer
	y as integer
endtype

`Maximum number of points
maxPoints as integer = 100

dim points(maxPoints) as pointType

`Number of starting points (has to be at least 4)
numPoints as integer = 4
`Number of points between main points (displaying the curve)
numSections as integer = 50

pointSelected as integer
mouseHold as integer
spaceHold as integer

`Randomize the starting points coordinates
points(1).x = rnd(600)+100
points(1).y = rnd(400)+100
points(2).x = rnd(600)+100
points(2).y = rnd(400)+100
points(3).x = rnd(600)+100
points(3).y = rnd(400)+100
points(4).x = rnd(600)+100
points(4).y = rnd(400)+100

`Create the vectors 1 to 5
tmp = make vector2(1)
tmp = make vector2(2)
tmp = make vector2(3)
tmp = make vector2(4)
tmp = make vector2(5)

sync on
sync rate 0

do
	`Control addition of points
	if mouseclick() = 2 and numPoints < maxPoints and mouseHold = 0
		inc numPoints
		points(numPoints).x = mousex()
		points(numPoints).y = mousey()
	endif
	
	`Control deletion of points
	if spacekey() = 1
		if numPoints > 4 and spaceHold = 0
			dec numPoints
		endif
		spaceHold = 1
	else
		spaceHold = 0
	endif

	ink rgb(255,255,0),0
	`Loop through all points
	for x = 1 to numPoints
		if mouseclick() = 1
			if mousex() >= points(x).x-3 and mousex() <= points(x).x+3 and mousey() >= points(x).y-3 and mousey() <= points(x).y+3 and mouseHold = 0
				pointSelected = x
			endif
		endif
		box points(x).x-2,points(x).y-2,points(x).x+2,points(x).y+2
	next x
	
	`Allow one click selection
	if mouseclick() <> 0
		mouseHold = 1
	endif
	
	`Move selected point if there is one
	if pointSelected <> 0
		points(pointSelected).x = mousex()
		points(pointSelected).y = mousey()
	endif
	
	ink rgb(255,255,255),0
	`Loop through all active points
	for x = 3 to numPoints-1
		`Fill vectors with point coordinates
		set vector2 1,points(x-2).x,points(x-2).y
		set vector2 2,points(x-1).x,points(x-1).y
		set vector2 3,points(x).x,points(x).y
		set vector2 4,points(x+1).x,points(x+1).y
		
		`Loop through the sections between points
		for y = 1 to numSections-1
			`Work out point on catmull rom spline (filledVector,pointA,pointB,pointC,pointD,value (0.0 = beginning of curve, 1.0 = end of curve, 0.5 = half way down curve))
			catmullrom vector2 5,1,2,3,4,1.0/numSections*y
			`Draw point
			dot x vector2(5),y vector2(5)
		next y
	next x

	`Draw lines between end points and 2nd end points	
	ink rgb(0,0,255),0
	line points(1).x,points(1).y,points(2).x,points(2).y
	ink rgb(0,255,0),0
	line points(numPoints-1).x,points(numPoints-1).y,points(numPoints).x,points(numPoints).y

	`Reset one click variable and point selected if no mouse is clicked
	if mouseclick() = 0
		mouseHold = 0
		pointSelected = 0
	endif
	
	`Info
	ink rgb(255,255,255),0
	text 10,10,"2D Catmull Rom Splines"
	text 10,25,"By Joseph Thomson 18/04/04"
	text 10,45,"LMB to move points"
	text 10,60,"RMB to add a point"
	text 10,75,"Space bar to delete the last point"
	
	sync
	cls
loop