We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Creating a bezier curve using toxi's geomutils
Page Index Toggle Pages: 1
Creating a bezier curve using toxi's geomutils (Read 2374 times)
Creating a bezier curve using toxi's geomutils
Apr 23rd, 2009, 3:00am
 
Hi all.  I'm currently trying to write a function that takes 4 random locations in 3D space (pointList[]) and creates a bezier curve between pointList[1] and pointList[2].  I'm looking to eventually create a nice smooth path for my camera as it moves between photos which are suspended at random positions in an OpenGL scene.

I think the best bet is to use Processing's bezierPoint which requires start, controlPoint1, controlPoint2, and end values.  I'm also using Toxi's excellent geomutils library, and although I'm testing all this with Vec2D, I'm confident the functions I use will translate easily into Vec3D.

So far, I can work out the angle required for both control points, but when I implement this through the various Vec functions, the vector created using the getRotated function doesn't match the calculated angle.

I have a demonstration sketch here http://openprocessing.org/visuals/?visualID=1773 which probably explains the problem a little better.  When the sketch starts, the 2 control point locations are calculated correctly.  However, when moving any of the location points (click and drag to move), although the control point angles are correct, the control point locations don't reflect this, and the whole sketch starts acting a little loopy (according to my own fuzzy mathematics).

I have a feeling it has something to do with whether each vector is rotated more than 90 degrees to the last, and whether the vector's direction is positive or negative on each axis.

Any ideas how I can solve this?  Thanks for any help you can give me.
Re: Creating a bezier curve using toxi's geomutils
Reply #1 - Apr 25th, 2009, 7:49pm
 
Hey!  I managed to find the info I needed!  Here's my camera class (which also now includes ease-in/ease-out function too!):
Code:
class CamObjTween {

Vec3D loc, cp1, cp2, offset;

CamObjTween(Vec3D _start, Vec3D _offset) {
loc = new Vec3D(_start);
offset = new Vec3D(_offset);
}


// Update location using bezier curves only

void Update(float _interpol, Vec3D[] _list) {
this.Update(_interpol, _list, 0, 0);
}


// Update location using bezier curves and easing

void Update(float _interpol, Vec3D[] _list, float easeIn, float easeOut) {
Vec3D l1 = _list[1].add(offset);
Vec3D l2 = _list[2].add(offset);

if (easeIn != 0 || easeOut != 0) _interpol = this.Ease(_interpol, easeIn, easeOut);

loc.x = bezierPoint(l1.x, cp1.x, cp2.x, l2.x, _interpol);
loc.y = bezierPoint(l1.y, cp1.y, cp2.y, l2.y, _interpol);
loc.z = bezierPoint(l1.z, cp1.z, cp2.z, l2.z, _interpol);
}


// Update location using easing only

void Update(float _interpol, Vec3D _target, float easeIn, float easeOut) {
_target.addSelf(offset);
loc = loc.interpolateTo(_target, this.Ease(_interpol, easeIn, easeOut));
}


// Set an offset (useful for camera eye)

void SetOffset(Vec3D _offset) {
offset = _offset;
}


// Function that sets the control points (use when new target added)
// Smoothing can be from 0.0 to 1.5, with 1.0 optimum

void SetCurve(Vec3D[] _list, float smoothing) {
cp1 = this.GetControlPoint(_list[0], _list[1], _list[2], smoothing);
cp2 = this.GetControlPoint(_list[3], _list[2], _list[1], smoothing);
}


// Function to find control points for bezier curves
// Thanks to efg's computer lab: http://www.efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm :
// "Geometrical control points construction" section

Vec3D GetControlPoint(Vec3D p1, Vec3D p2, Vec3D p3, float smoothing) {
Vec3D middle = p2.interpolateTo(p3, 0.5);
Vec3D p4 = p2.sub(p1).limit(middle.magnitude()).scale(smoothing).scale(0.5).add(p2);
Vec3D _cp = middle.interpolateTo(p4, 0.5);
return _cp;
}

// Easing function
// Thanks to "Computer animation: algorithms and techniques" by
// Rick Parent, p87-89 "Sinusodial Pieces for Acceleration and Deceleration"

float Ease(float t, float k1, float k2) {
float t1, t2;
float f, s;
f = k1*2/PI + k2 - k1 + (1.0-k2)*2/PI;
if (t < k1) {
s = k1*(2/PI)*(sin((t/k1)*PI/2-PI/2)+1);
} else if (t < k2) {
s = (2*k1/PI + t-k1);
} else {
s = 2*k1/PI + k2-k1 + ((1-k2)*(2/PI))*sin(((t-k2)/(1.0-k2))*PI/2);
}
return (s/f);
}
}
Re: Creating a bezier curve using toxi's geomutils
Reply #2 - Apr 28th, 2009, 8:00am
 
Hey, are you aware that there's a 2D/3D spline class in toxiclibs It is mainly meant for curve smoothing from a list of corner points the curve has to go through, but it will figure out control points/handles automatically. See a 2D example over here:

http://processing.org/discourse/yabb2/num_1229440845.html#2

Also, there was an issue with rotateX() in Vec3D, which has been fixed in the latest version of the library core package (only released last week):

http://code.google.com/p/toxiclibs/issues/detail?id=7

Hth!
Re: Creating a bezier curve using toxi's geomutils
Reply #3 - May 11th, 2009, 5:11pm
 
toxi - I have been trying to figure out the math for beziers but I'm going to drop it and just use you library - it sounds perfect. Just one question - is there a way to adjust the length of the handles which would have an impact on the curvature around each vertiex?
Re: Creating a bezier curve using toxi's geomutils
Reply #4 - Jun 4th, 2009, 4:45pm
 
oompa_l, I guess it might probably be too late already to still help you, but I've just uploaded a new version of the toxiclibs-core package which has a bug fix (unrelated to this here) and a new parameter to control the curve tangent/tightness.

http://toxiclibs.org/
or
http://toxiclibs.googlecode.com/files/toxiclibscore-0014.zip (direct download)

The downloads include a demo showing how to use this all. Also see the image below for the different effects you can achieve (can get much more extreme too, if you wish so...)

http://www.flickr.com/photos/toxi/3570347396/
Re: Creating a bezier curve using toxi's geomutils
Reply #5 - Nov 4th, 2009, 4:07pm
 
Toxi, just wondering if using your library to create let's say 20,000 lines would be any faster than using (GL_LINES).  Always looking for ways to boost performance.
Page Index Toggle Pages: 1