| |||||||||||||||||||||||||||||||
|
probably worth sharing, so apologies to the OP. It was in reference to an old message about drawing sin curves. > Hi Danny, I'd love to see your code if you wouldn't mind. I'm > looking for something similar too and Catmull-Rom splines are > way beyond where I'm at.. :P All right, the first answer is: here's the code (sorry, it's Lingo but it should be easy enough to translate - note that Lingo arrays are 1-based rather than 0-based) that converts a sequence of points cubic bezier curve: on convertPointsToBezierCurve tCatmullPoints -- add two dummy points to the end tCatmullPoints.add(tCatmullPoints[tCatmullPoints.count]) tCatmullPoints.add(tCatmullPoints[tCatmullPoints.count]) -- and one at the beginning tCatmullPoints.addAt(1,tCatmullPoints[1]) tVertexList = [] tNextControl = point(0,0) repeat with i = 2 to tCatmullPoints.count-2 tNextControl = (tCatmullPoints[i] - tCatmullPoints[i+2])/6 tControl = (tCatmullPoints[i+1] - tCatmullPoints[i-1])/6 tVertexList.add([#vertex:tCatmullPoints[i], #handle2:tNextControl, #handle1:tControl]) end repeat tVertexList.add([#vertex:tCatmullPoints[i], #handle2:tNextControl, #handle1:point(0,0)]) return tVertexList end Second answer is: here's a better way to convert a series of points into a series of *quadratic* beziers. I'll assume that you already know the correct tangent at each point (which is true if you're generating the points from a function like sin). If not, you need to calculate some tangents first, perhaps by using the function above. As I'm only writing this now, I'll do it straight into AS. This function takes a list of N+1 points and N+1 tangents (each of which is a 2-element array rather than a point object, although it would be easy to make them points instead), and returns a list of N control points. I can give you the explanation if you want, but the basic idea is that each control point must lie on the intersection of the tangent from both neighbouring points. I've left out the error checking that would be sensible to include! function getBezierPoints(tPoints:Array, tTangents:Array):Array { var tControls:Array = new Array() for (var i=1; i<tPoints.length; i++) { var tP1 = tPoints[i] var tP0 = tPoints[i-1] var tT1 = tTangents[i] var tT0 = tTangents[i-1] var s = ((tP1[0] - tP0[0])*tT0[1] - (tP1[1] - tP0[1])*tT0[0]) / (tT1[0]*tT0[1] - tT1[1]*tT0[0]) tControls.push(new Array(tP1[0] - s*tT1[0], tP1[1] - s*tT1[1])) } return tControls } To test it, try this: m = _root.createEmptyMovieClip("wave", 1) m._x = 20 m._y = 200 drawSinCurve(m, 50,0,0.1) // experiment with these values to draw different curves function drawSinCurve(tMC:MovieClip, tAmp:Number, tPhase:Number, tFrequency:Number):Void { var tPoints:Array = new Array(); var tTangents:Array = new Array(); var tInc = 0.05/tFrequency // this value affects the accuracy of the curve for (var x = 0; x < 400; x += tInc) { var tP = x * tFrequency + tPhase; tPoints.push(new Array(x, tAmp * Math.sin(tP))); tTangents.push(new Array(1, tAmp * tFrequency * Math.cos(tP))); } var tControls:Array = getBezierPoints(tPoints, tTangents); tMC.beginFill() tMC.lineStyle(1) tMC.moveTo(tPoints[0][0], tPoints[0][1]); for (var i = 1; i < tPoints.length; i++) { tMC.curveTo(tControls[i - 1][0], tControls[i - 1][1], tPoints[i][0], tPoints[i][1]); } } Best Danny _______________________________________________ Flashcoders To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com
| ||||||||||||||||||||||||||||||
© 2004-2008 readlist.com