[Closed] bezier curves without bezier curves
well, since talked to eek and mark about this stuff a while ago… i had to give it a shot myself now that i had some time
this is a simple function that takes 4 helpers as input, and creates a point that is constrained to the bezier curve defined by these for helpers
note that this only works with exactly 4 points (a special case of a bezier curve which is faster to calculate than a general bezier), 4 points is what makes sense for spine setups as well as probably for curvy limbs my opinion.
here’s where i got the formula from (contain’s c++ code that can easily be translated into maxscript or a max expression)
hope this helps anyone out there!
to test it, select 4 objects and run the script
it’s very fast already, but if anyone has an idea how to speed up the script controller itself, i’m all ears
fn
createBezierPoint
points -- array of 4 objects to define the curve (1 and 4 are the control points, 2 and 3 are control handles)
u: -- position of the point along the curve (value range 0 to 1), this can either be a float value or a float subanim
=
(
try
(
if points.count != 4 then throw ("need 4 points, got " + points.count as string)
local theP = point centerMarker:true axisTriped:false cross:false box:false size:0 constantScreenSize:false drawOnTop:false
local cnt = position_script()
theP.pos.controller = cnt
for i=1 to 4 do
(
if not isValidNode points[i] then throw ("point " + i as string + " not a valid node")
cnt.addNode ("p" + i as string) points[i]
)
case (classof u) of (
float: cnt.addConstant "mu" u
subAnim: if classof u.value == float then cnt.addTarget "mu" u else throw ("u subAnim value needs to be a float")
default: throw ("invalid value for 'u', need either float or float subanim, got " + (classof u) as string)
)
cnt.setExpression \
"p1 = p1.transform[4]
p2 = p2.transform[4]
p3 = p3.transform[4]
p4 = p4.transform[4]
mum1 = 1 - mu
mum13 = mum1^3
mu3 = mu^3
(mum13*p1 + 3*mu*mum1^2*p2 + 3*mu^2*mum1*p3 + mu3*p4)"
return theP
)catch(throw())
)
try(for i=0.0 to 1.0 by 0.1 do createBezierPoint (selection as array) u:i)catch(format "%
" (getCurrentException()))
I get the following error.
[size=3]-- Unknown property: "addNode" in Controller:Position_Script
[/size]
What version does this work on?
Stev
oh right, it only works with max 8’s new script controllers
you’d have to put a dependson statement within the script referring to all 4 points by name
General bezier dont exactly exist, thats a quadratic curve – a generalisation through a series of control points which uses the cox-de boor equation. Bezier curves, use the bernstien polynormial, as you have it at the bottom of your fn. And are base on the rule of 2 end knots and 2 tangents. It makes it fast as you dont have to walk the spline. And for b-spline you can also call the same equation again and again on each segment your in.
Quadratic is the order of 1 its the simplist defined curve, bezier is 2, b-spline and non-uniform b-spline is 3 as you have to define a generalization for the cubic polynormial to work it.
Cardinal, Nurbs, and bspline use the same equation, its how you define the vectors for this equation is key. With besier you give it the tangents as there exposed, with cardinal and Nurbs these have to be defined through the generalization. And also special exceptions are needed for the ends of these curves. (the tangent problem)
Pretty slick. I should have paid more attention in math class.
haha – don’t think i did
thanky for the additional info eek. makes sense about using the same equation for all segments, i’ll try to implement that when i get the chance!