Updated the bezier curve Library to 3d (just wanted to share)
_BC_Setup:
global bc_lastcurvepointx#=0.0
global bc_lastcurvepointy#=0.0
global bc_lastcurvepointz#=0.0
global bc_curvepointcount=0
global bc_distanceiterations=2000
global bc_closestdistance#=0.0
global bc_closestpointx#=0.0
global bc_closestpointy#=0.0
global bc_closestpointz#=0.0
global bc_closestindex=0
global bc_curvesegmentpointcount=0
type bc_curvepointinfo
posx# as float
posy# as float
posz# as float
endtype
type bc_curvesegmentpointinfo
posx# as float
posy# as float
posz# as float
endtype
dim bc_curvepoint[0] as bc_curvepointinfo
dim bc_curvesegmentpoint[0] as bc_curvesegmentpointinfo
return
function BC_AddCurvePoint(posx#,posy#,posz#)
bc_curvepointcount=bc_curvepointcount+1
dim bc_curvepoint[bc_curvepointcount] as bc_curvepointinfo
bc_curvepoint[bc_curvepointcount-1].posx#=posx#
bc_curvepoint[bc_curvepointcount-1].posy#=posy#
bc_curvepoint[bc_curvepointcount-1].posz#=posz#
endfunction
function BC_RemoveCurvePoints()
bc_curvepointcount=0
dim bc_curvepoint[bc_curvepointcount] as bc_curvepointinfo
bc_curvesegmentpointcount=0
dim bc_curvesegmentpoint[bc_curvesegmentpointcount] as bc_curvesegmentpointinfo
endfunction
function BC_CalculatePointOnOpenCurve(t#) //t# is the percentage of the way along the line in a range of 0-1
// thresh#=0.3333
// curve#=0.5
thresh#=0.3
curve#=0.5
if bc_curvepointcount>1
totalt#=t#*(bc_curvepointcount-1)
i=trunc(totalt#)
realt#=totalt#-i
p1posx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,thresh#)
p1posy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,thresh#)
p1posz#=bc_pointonlinez(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,thresh#)
p2posx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,thresh#)
p2posy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,thresh#)
p2posz#=bc_pointonlinez(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,thresh#)
if i=0
p0posx#=bc_curvepoint[i].posx#
p0posy#=bc_curvepoint[i].posy#
p0posz#=bc_curvepoint[i].posz#
else
tempx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,bc_curvepoint[i-1].posz#,thresh#)
tempy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,bc_curvepoint[i-1].posz#,thresh#)
tempz#=bc_pointonlinez(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,bc_curvepoint[i-1].posz#,thresh#)
p0posx#=bc_pointonlinex(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,curve#)
p0posy#=bc_pointonliney(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,curve#)
p0posz#=bc_pointonlinez(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,curve#)
endif
if i=bc_curvepointcount-2
p3posx#=bc_curvepoint[i+1].posx#
p3posy#=bc_curvepoint[i+1].posy#
p3posz#=bc_curvepoint[i+1].posz#
else
tempx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,bc_curvepoint[i+2].posz#,thresh#)
tempy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,bc_curvepoint[i+2].posz#,thresh#)
tempz#=bc_pointonlinez(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,bc_curvepoint[i+2].posz#,thresh#)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,curve#)
p3posy#=bc_pointonliney(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,curve#)
p3posz#=bc_pointonlinez(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,curve#)
endif
//begin calculations (conveniently adapted from http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/):
u#=1-realt#
tt#=realt#*realt#
uu#=u#*u#
uuu#=uu#*u#
ttt#=tt#*realt#
bc_lastcurvepointx#=uuu#*p0posx# //first term
bc_lastcurvepointy#=uuu#*p0posy# //first term
bc_lastcurvepointz#=uuu#*p0posz# //first term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*uu#*realt#*p1posx# //second term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*uu#*realt#*p1posy# //second term
bc_lastcurvepointz#=bc_lastcurvepointz#+3*uu#*realt#*p1posz# //second term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*u#*tt#*p2posx# //third term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*u#*tt#*p2posy# //third term
bc_lastcurvepointz#=bc_lastcurvepointz#+3*u#*tt#*p2posz# //third term
bc_lastcurvepointx#=bc_lastcurvepointx#+ttt#*p3posx# //fourth term
bc_lastcurvepointy#=bc_lastcurvepointy#+ttt#*p3posy# //fourth term
bc_lastcurvepointz#=bc_lastcurvepointz#+ttt#*p3posz# //fourth term
else
if bc_curvepointcount>0
bc_lastcurvepointx#=bc_curvepoint[0].posx#
bc_lastcurvepointy#=bc_curvepoint[0].posy#
bc_lastcurvepointz#=bc_curvepoint[0].posz#
else
message("Bezier Curve Library: Tried to calculate a curve with no points! You douchebag!")
end
endif
endif
endfunction
function BC_CalculatePointOnClosedCurve(t#) //t# is the percentage of the way along the line in a range of 0-1
if bc_curvepointcount>1
totalt#=t#*bc_curvepointcount
i=trunc(totalt#)
realt#=totalt#-i
if i=bc_curvepointcount-1
p1posx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,0.3333)
p1posy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,0.3333)
p1posz#=bc_pointonlinez(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,0.3333)
p2posx#=bc_pointonlinex(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,0.3333)
p2posy#=bc_pointonliney(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,0.3333)
p2posz#=bc_pointonlinez(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,0.3333)
else
p1posx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,0.3333)
p1posy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,0.3333)
p1posz#=bc_pointonlinez(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,0.3333)
p2posx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,0.3333)
p2posy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,0.3333)
p2posz#=bc_pointonlinez(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,0.3333)
endif
if i=0
tempx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[bc_curvepointcount-1].posx#,bc_curvepoint[bc_curvepointcount-1].posy#,bc_curvepoint[bc_curvepointcount-1].posz#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[bc_curvepointcount-1].posx#,bc_curvepoint[bc_curvepointcount-1].posy#,bc_curvepoint[bc_curvepointcount-1].posz#,0.3333)
tempz#=bc_pointonlinez(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[bc_curvepointcount-1].posx#,bc_curvepoint[bc_curvepointcount-1].posy#,bc_curvepoint[bc_curvepointcount-1].posz#,0.3333)
p0posx#=bc_pointonlinex(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,0.5)
p0posy#=bc_pointonliney(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,0.5)
p0posz#=bc_pointonlinez(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,0.5)
else
tempx#=bc_pointonlinex(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,bc_curvepoint[i-1].posz#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,bc_curvepoint[i-1].posz#,0.3333)
tempz#=bc_pointonlinez(bc_curvepoint[i].posx#,bc_curvepoint[i].posy#,bc_curvepoint[i].posz#,bc_curvepoint[i-1].posx#,bc_curvepoint[i-1].posy#,bc_curvepoint[i-1].posz#,0.3333)
p0posx#=bc_pointonlinex(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,0.5)
p0posy#=bc_pointonliney(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,0.5)
p0posz#=bc_pointonlinez(tempx#,tempy#,tempz#,p1posx#,p1posy#,p1posz#,0.5)
endif
if i=bc_curvepointcount-2
tempx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,0.3333)
tempz#=bc_pointonlinez(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
p3posz#=bc_pointonlinez(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
else
if i=bc_curvepointcount-1
tempx#=bc_pointonlinex(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,bc_curvepoint[1].posx#,bc_curvepoint[1].posy#,bc_curvepoint[1].posz#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,bc_curvepoint[1].posx#,bc_curvepoint[1].posy#,bc_curvepoint[1].posz#,0.3333)
tempz#=bc_pointonlinez(bc_curvepoint[0].posx#,bc_curvepoint[0].posy#,bc_curvepoint[0].posz#,bc_curvepoint[1].posx#,bc_curvepoint[1].posy#,bc_curvepoint[1].posz#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
p3posz#=bc_pointonlinez(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
else
tempx#=bc_pointonlinex(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,bc_curvepoint[i+2].posz#,0.3333)
tempy#=bc_pointonliney(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,bc_curvepoint[i+2].posz#,0.3333)
tempz#=bc_pointonlinez(bc_curvepoint[i+1].posx#,bc_curvepoint[i+1].posy#,bc_curvepoint[i+1].posz#,bc_curvepoint[i+2].posx#,bc_curvepoint[i+2].posy#,bc_curvepoint[i+2].posz#,0.3333)
p3posx#=bc_pointonlinex(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
p3posy#=bc_pointonliney(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
p3posz#=bc_pointonlinez(p2posx#,p2posy#,p2posz#,tempx#,tempy#,tempz#,0.5)
endif
endif
//begin calculations (conveniently adapted from http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/):
u#=1-realt#
tt#=realt#*realt#
uu#=u#*u#
uuu#=uu#*u#
ttt#=tt#*realt#
bc_lastcurvepointx#=uuu#*p0posx# //first term
bc_lastcurvepointy#=uuu#*p0posy# //first term
bc_lastcurvepointz#=uuu#*p0posz# //first term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*uu#*realt#*p1posx# //second term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*uu#*realt#*p1posy# //second term
bc_lastcurvepointz#=bc_lastcurvepointz#+3*uu#*realt#*p1posz# //second term
bc_lastcurvepointx#=bc_lastcurvepointx#+3*u#*tt#*p2posx# //third term
bc_lastcurvepointy#=bc_lastcurvepointy#+3*u#*tt#*p2posy# //third term
bc_lastcurvepointz#=bc_lastcurvepointz#+3*u#*tt#*p2posz# //third term
bc_lastcurvepointx#=bc_lastcurvepointx#+ttt#*p3posx# //fourth term
bc_lastcurvepointy#=bc_lastcurvepointy#+ttt#*p3posy# //fourth term
bc_lastcurvepointz#=bc_lastcurvepointz#+ttt#*p3posz# //fourth term
else
if bc_curvepointcount>0
bc_lastcurvepointx#=bc_curvepoint[0].posx#
bc_lastcurvepointy#=bc_curvepoint[0].posy#
bc_lastcurvepointz#=bc_curvepoint[0].posz#
else
message("Bezier Curve Library: Tried to calculate a curve with no points! You douchebag!")
end
endif
endif
endfunction
function BC_GetCurvePointCount()
endfunction bc_curvepointcount
function BC_GetCurvePointX()
endfunction bc_lastcurvepointx#
function BC_GetCurvePointY()
endfunction bc_lastcurvepointy#
function BC_GetCurvePointZ()
endfunction bc_lastcurvepointz#
function BC_CalculateClosestPointToCurve(posx#,posy#,posz#) //x# and y# are the point from which we're searching
bc_closestdistance#=1000000 //hack, but basically could never be larger than this anyway
if bc_curvepointcount>0
bc_closestpointx#=0
bc_closestpointy#=0
bc_closestpointz#=0
for i=0 to bc_distanceiterations-1
distance#=bc_distance(posx#,posy#,posz#,bc_curvesegmentpoint[i].posx#,bc_curvesegmentpoint[i].posy#,bc_curvesegmentpoint[i].posz#)
if distance#<bc_closestdistance#
bc_closestdistance#=distance#
bc_closestpointx#=bc_curvesegmentpoint[i].posx#
bc_closestpointy#=bc_curvesegmentpoint[i].posy#
bc_closestpointz#=bc_curvesegmentpoint[i].posz#
bc_closestindex=i
endif
next i
else
bc_closestpointx#=0
bc_closestpointy#=0
bc_closestpointz#=0
endif
endfunction
function BC_GetClosestPointX()
endfunction bc_closestpointx#
function BC_GetClosestPointY()
endfunction bc_closestpointy#
function BC_GetClosestPointZ()
endfunction bc_closestpointz#
function BC_GetClosestPointDistance()
endfunction bc_closestdistance#
function BC_GetClosestPointIndex()
endfunction bc_closestindex
function BC_SetCurveSegmentPointCount(count)
bc_distanceiterations=count
endfunction
function BC_GetCurveSegmentPointCount()
endfunction bc_curvesegmentpointcount
function BC_GetCurveSegmentPointX(index)
x#=bc_curvesegmentpoint[index].posx#
endfunction x#
function BC_GetCurveSegmentPointY(index)
y#=bc_curvesegmentpoint[index].posy#
endfunction y#
function BC_GetCurveSegmentPointZ(index)
z#=bc_curvesegmentpoint[index].posz#
endfunction z#
function BC_CalculateOpenCurveSegmentPoints()
bc_curvesegmentpointcount=bc_distanceiterations
dim bc_curvesegmentpoint[bc_curvesegmentpointcount] as bc_curvesegmentpointinfo
if bc_curvepointcount>0
add#=1.0/bc_distanceiterations
t#=0
for i=0 to bc_curvesegmentpointcount-1
bc_calculatepointonopencurve(t#)
bc_curvesegmentpoint[i].posx#=bc_lastcurvepointx#
bc_curvesegmentpoint[i].posy#=bc_lastcurvepointy#
bc_curvesegmentpoint[i].posz#=bc_lastcurvepointz#
t#=t#+add#
next i
endif
endfunction
function BC_CalculateClosedCurveSegmentPoints()
bc_curvesegmentpointcount=bc_distanceiterations
dim bc_curvesegmentpoint[bc_curvesegmentpointcount] as bc_curvesegmentpointinfo
if bc_curvepointcount>0
add#=1.0/bc_distanceiterations
t#=0
for i=0 to bc_curvesegmentpointcount-1
if i=bc_distanceiterations-1 then t#=0.9999999
bc_calculatepointonclosedcurve(t#)
bc_curvesegmentpoint[i].posx#=bc_lastcurvepointx#
bc_curvesegmentpoint[i].posy#=bc_lastcurvepointy#
bc_curvesegmentpoint[i].posz#=bc_lastcurvepointz#
t#=t#+add#
next i
endif
endfunction
// this should be really checked I changed a lot
function BC_Distance(x1#,y1#,z1#,x2#,y2#,z2#)
dx#=x1#-x2#
dy#=y1#-y2#
dz#=z1#-z2#
distance#=sqrt(dx#*dx#+dy#*dy#+dz#*dz#)
endfunction distance#
function BC_PointOnLineX(x1#,y1#,z1#,x2#,y2#,z2#,percent#)
px#=x1#+((x2#-x1#)*percent#)
endfunction px#
function BC_PointOnLineY(x1#,y1#,z1#,x2#,y2#,z2#,percent#)
py#=y1#+((y2#-y1#)*percent#)
endfunction py#
function BC_PointOnLineZ(x1#,y1#,z1#,x2#,y2#,z2#,percent#)
pz#=z1#+((z2#-z1#)*percent#)
endfunction pz#