ActionScript curves update

I finally opened my CubicBezier AS3 class, the only reason anyone ever finds this site at all, for the first time in many months to attempt to address some of the various comments and reported problems from the original. It’s not perfected, but I’ve done three things:

  1. Added a “moveTo” argument to the curveThroughPoints method, following the idea in one comment on my blog post. Ignore it if you wish, but if you set it to false, the curves will connect to wherever graphics drawing left off rather than moving to the beginning of the curve and starting anew.
  2. Hooray trigonometry! Messed with some of the angle calculations to fix problems with zero angles and division by zero. I hope it worked.
  3. Provided a line of code that can be altered to use lineTo for straight segments of 3 or more points rather than curving.

Straight lines were raised as an issue in several comments. While I think I have fixed the crazy behavior of straight horizontal and vertical lines, I suspect the result for three points in a line may be surprising at first glance. For instance, the three middle points in the image below are all aligned horizontally.

Straight line with S-curve

The S-curve through those points may look odd at first, but it’s actually to be expected with these cubic Bézier curves. Of those three points, only the middle one has curve control points that are also aligned horizontally. The outer two have control points that are also based on the points outside the line. Here’s an approximate example from Illustrator of what they look like

S-curve in Illustrator

I’ve left that as the default behavior, but I did insert some code that can be modified so that the curve essentially stops curving when it reaches several points in a line, draws a straight line through them, and then continues curving as normal after that. Here’s what the same example looks like with that option enabled.

Straight line with lineTo

It’s probably often fine, but I caution that it can result in sharp corners. Here’s the same with those dots removed:

Straight line with lineTo and sharp corners

I’m uncertain what’s best, so I’ve made that a line of code that has to be changed rather than a more accessible option. I’d be glad to hear ideas on how best to handle it. Feel free to change it however you like, of course. That and other modifications are identified in the comments.

Download the class here: CubicBezier.as
The previous version is here, in case I screwed something up. Forgive my lack of version control.

Tagged , ,

26 Comments

  1. Hey Andy, thanks for your work on this. I feel like I come across your and Zach’s blog half the time I google for something actionscript :) . I’ve been playing around with your class lately. I just tried the new one with straightLines:Boolean = true, just for kicks, but I got an error:

    TypeError: Error #1010: A term is undefined and has no properties.

    I get the feeling that it’s a problem on my side. It does work properly with straightLines = false though.

    Nathan
    5 January 2009 @ 7:17pm

  2. Thanks for the report. I’ll admit I didn’t do too much testing with that. It probably has to do with the Math.atan2 operations it tries to do if straightLines = true. It’s looking two positions ahead in the array of points, which I thought would work, but it’s probably getting to the end of the array (though only sometimes, apparently, since I have gotten it to work). I’ll have a look at it.

    Andy Woodruff
    5 January 2009 @ 8:16pm

  3. The file has been updated to (I hope) fix the above error. I’m not honestly sure how well the straight line thing will work, but there are some extra conditions now to try to keep it from breaking.

    Andy Woodruff
    6 January 2009 @ 11:47am

  4. Hey, Great class here. I am curious to know if there is a way to have the new curve that is drawn through continuous points the only output of the class. I am having issues where it is drawing a line through the original points as well as the new curved ones. Ultimately, I want to fill the space between the new points as one solid mass. Any help would be appreciated.

    MG
    29 January 2009 @ 10:06am

  5. OK. I figured it out…Such a silly mistake…those are usually the hardest to decode. Again…great class.

    MG
    29 January 2009 @ 11:14am

  6. Very interesting system you put together, thanks for commenting you .as file so heavily.

    Geoff
    30 January 2009 @ 5:45pm

  7. Thanks so much for putting this out there — It’s very helpful and your commenting made it really easy to adjust.

    Nikki
    5 February 2009 @ 12:26pm

  8. It recently dawned on me that the sharp corners I mentioned could be avoided by moving the control points of the curves entering and exiting the straight line so that they lie on the same line. Something like this:
    Curves with straight line but no sharp corners
    Should have thought of that before. I’ll try to work that in if/when I do further updates.

    Andy Woodruff
    9 March 2009 @ 11:34am

  9. Hi Andy,
    Thanks so much for your report.
    But is there any way to close the curve?
    Can you help me?

    Thx ~

    Henky
    10 March 2009 @ 5:03am

  10. You should be able to close the curve simply by making the first and last points the same.

    Andy Woodruff
    10 March 2009 @ 8:12am

  11. to import it in flex??
    i have ho idea why fl.* pack is not loaded

    asd
    26 May 2009 @ 3:41am

  12. fl.* package is not part of flex.
    Its a package shipped with flash CS3 (i guess with CS4 too)
    The default location is:
    C:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\ActionScript 3.0\Classes\fl\

    sydd
    30 June 2009 @ 5:35am

  13. Heya, do you happen to know if there is a similar solution for Flex, aside from the Degrafa library. Since I only need this one for my grand project pathfinding rendering engine :) I love it and it works smooth enough, but since I’m building it based on an AS3 project in Flashdevelop, it is basically Flex and can’t use natively FL – library stuff. I’ve circumvented it by using a swc with the necessary controls and this lovely cubicbezier class, but it’s a bit messy and I’d rather have it all in Flex :)

    Once again thank you for this, cheers

    -N

    Poetus
    11 July 2009 @ 1:03pm

  14. I don’t know of similar single Flex solutions, although I haven’t really looked. When originally writing this, I hadn’t even considered Flex and that that Flash CS3/4 would contain packages not available in Flex. So this was interesting to learn.

    Andy Woodruff
    12 July 2009 @ 11:06am

  15. Hey, we built a small fast bezier library for AS3, we’ve open sourced it so feel free to give it a try:

    http://farmcode.org/post/2009/07/06/Fast-2D-Bezier-Library-for-ActionScript-3.aspx

    Tom
    12 July 2009 @ 7:28pm

  16. Thanks for sharing that, Tom; I will definitely check it out. (Sorry your comment didn’t show up right away. It was caught by the spam filter for some reason.)

    Andy Woodruff
    17 July 2009 @ 11:37am

  17. Thanks for sharing your code !
    I wonder if there is a way to mix your class with the dashLine class to be able to draw curve dashLine.

    tron
    26 November 2010 @ 11:47am

  18. Don´t you ever use type declarations??

    Sebastian
    3 December 2010 @ 5:18am

  19. I realize this is a ridiculously basic question, but I’m trying to learn Bezier curves and ActionScript at the same time. I understand what’s going on with the curve itself, but in your code you use GreenDot and ControlPoint. Where are those defined?

    Zoi
    15 April 2011 @ 7:44pm

  20. I found your zip file on the older version, but it might be good to include it on this page as well. Thanks for sharing! I’ll be trying your code.
    [www.userinteraction.net]

    Brendan
    22 February 2012 @ 12:38am

  21. Thanks very much! Works like heaven!

    Ivan
    29 March 2013 @ 7:57am