PDA

View Full Version : bezier curves without bezier curves


Aearon
04-01-2006, 08:32 AM
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 (http://astronomy.swin.edu.au/%7Epbourke/curves/bezier/) 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 "%\n" (getCurrentException()))

_stev_
04-01-2006, 09:08 AM
I get the following error.


-- Unknown property: "addNode" in Controller:Position_Script



What version does this work on?

Stev

Aearon
04-01-2006, 09:37 AM
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

_stev_
04-01-2006, 09:46 AM
Thanks man, I'm going to check it out.

Stev

eek
04-01-2006, 05:39 PM
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)

JHaywood
04-03-2006, 05:35 PM
Pretty slick. I should have paid more attention in math class. :)

Aearon
04-03-2006, 07:06 PM
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!

CGTalk Moderation
04-03-2006, 07:06 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.