Catmull-Rom spline:
#ifndef Tcoord
type Tcoord
x as single
y as single
End Type
#endif
type Tspline2d
Public:
'' constructors and destructors
declare constructor()
declare constructor(byval _maxpoints as integer)
declare destructor()
'' properties
'' getters
declare property x() as single
declare property y() as single
declare property t() as single
declare property speed() as single
declare property index() as integer
declare property maxindex() as integer
declare property p(byval _index as integer) as Tcoord
'' setters
declare property x(byval _n as single)
declare property y(byval _n as single)
declare property t(byval _n as single)
declare property speed(byval _n as single)
declare property index(byval _n as integer)
declare property maxindex(byval _n as integer)
declare property p(byval _index as integer, byval _value as Tcoord)
'' methods
declare sub initcoords(byval _maxpoints as integer)
declare sub update()
'' members
private:
m_x as single
m_y as single
m_t as single
m_speed as single
m_index as integer
m_maxindex as integer
p_coords as Tcoord ptr
end type
constructor Tspline2d()
m_t = 0
m_speed = 0.001
m_index = 0
m_maxindex = 0
end constructor
constructor Tspline2d(byval _maxpoints as integer)
m_t = 0
m_speed = 0.001
m_index = 0
m_maxindex = _maxpoints
p_coords = new Tcoord[_maxpoints]
end constructor
destructor Tspline2d()
delete[] p_coords
end destructor
'' properties
'' getters
property Tspline2d.x() as single
property = m_x
End Property
property Tspline2d.y() as single
property = m_y
End Property
property Tspline2d.t() as single
property = m_t
End Property
property Tspline2d.speed() as single
property = m_speed
End Property
property Tspline2d.index() as integer
property = m_index
End Property
property Tspline2d.maxindex() as integer
property = m_maxindex
End Property
property Tspline2d.p(byval _index as integer) as Tcoord
if _index > -1 and _index < m_maxindex then
property = p_coords[_index]
end if
End Property
'' setters
property Tspline2d.x(byval _n as single)
m_x = _n
End Property
property Tspline2d.y(byval _n as single)
m_y = _n
End Property
property Tspline2d.t(byval _n as single)
m_t = _n
End Property
property Tspline2d.speed(byval _n as single)
m_speed = _n
End Property
property Tspline2d.index(byval _n as integer)
m_index = _n
End Property
property Tspline2d.maxindex(byval _n as integer)
m_maxindex = _n
End Property
property Tspline2d.p(byval _index as integer, byval _n as Tcoord)
if _index > -1 and _index < m_maxindex then
p_coords[_index].x = _n.x
p_coords[_index].y = _n.y
end if
End Property
'' methods
sub Tspline2d.initcoords(byval _maxpoints as integer)
m_maxindex = _maxpoints
p_coords = new Tcoord[_maxpoints]
End Sub
sub Tspline2d.update()
dim as single t1 = m_t
dim as single t2 = t * t
dim as single t3 = t2 * t
dim as Tcoord p0, p1, p2, p3
p0.x = p_coords[m_index].x
p0.y = p_coords[m_index].y
p1.x = p_coords[(m_index + 1) mod m_maxindex].x
p1.y = p_coords[(m_index + 1) mod m_maxindex].y
p2.x = p_coords[(m_index + 2) mod m_maxindex].x
p2.y = p_coords[(m_index + 2) mod m_maxindex].y
p3.x = p_coords[(m_index + 3) mod m_maxindex].x
p3.y = p_coords[(m_index + 3) mod m_maxindex].y
m_x = 0.5 * ( ( 2.0 * p1.x ) +_
( -p0.x + p2.x ) * t1 +_
( 2.0 * p0.x - 5.0 * p1.x + 4 * p2.x - p3.x ) * t2 +_
( -p0.x + 3.0 * p1.x - 3.0 * p2.x + p3.x ) * t3 )
m_y = 0.5 * ( ( 2.0 * p1.y ) +_
( -p0.y + p2.y ) * t1 +_
( 2.0 * p0.y - 5.0 * p1.y + 4 * p2.y - p3.y ) * t2 +_
( -p0.y + 3.0 * p1.y - 3.0 * p2.y + p3.y ) * t3 )
'' increment t
m_t += m_speed
if m_t > 1.0 then
m_t -= 1.0
m_index = (m_index + 1) mod m_maxindex
endif
End Sub
cls
screen 18,,2
randomize timer
const MAXPOINTS = 10
dim as Tspline2d catmull '= Tspline2d(MAXPOINTS)
catmull.initcoords(MAXPOINTS)
for i as integer = 0 to catmull.maxindex-1
dim as Tcoord p
p.x = rnd * 640
p.y = rnd * 480
catmull.p(i) = p
next i
dim as integer current_color = 1, colorchanged = 0
catmull.speed = 0.005
screenset 0,1
for i as integer = 0 to catmull.maxindex-1
dim as Tcoord p
p = catmull.p(i)
circle (p.x,p.y), 3,i + 1
next i
do
'line (0,0)-(639,479),0,bf
catmull.update
'circle (catmull.x,catmull.y),15, current_color
pset (catmull.x,catmull.y),15
if catmull.index = 0 and colorchanged = 0 then
current_color = 1 + rnd * 15
colorchanged = -1
elseif catmull.index = 1 then
colorchanged = 0
end if
screensync
screencopy
Loop until inkey<>""