Hacker News new | ask | show | jobs
by shaftway 806 days ago
For bezier curves in Python try this:

    def bezier(t, *points):
      if len(points) <= 1:
        return points[0]

      next_set = []
      for i in range(1, len(points)):
        next_set.append([p[0] + t * (p[1] - p[0]) for p in zip(points[i - 1], points[i])])

      return bezier(t, *next_set)
That'll compute a point along your bezier curve. The `t` parameter is how far along the curve you want to go, 0 <= t <= 1. You can give it as many dimensions and whatever order (number of handles) you want. So for example, to get a cubic bezier curve on a 2d plane from (0, 0) to (1, 1) with handles at (1, 0), (0, 1) (an aggressive ease-in/ease-out curve) with 9 segments (10 points) you'd run:

    n = 10
    for t in range(n):
      print(
        bezier(
          t / (n - 1),
          (0, 0),
          (1, 0),
          (0, 1),
          (1, 1)
          ))
I think that's right. I did it from memory. Obviously don't mix 2d and 3d, but it should work if all points have the same number of dimensions.
2 comments

Oh, there is no guarantee about the spacing of these points. They won't be equidistant from each other, the points may cluster towards one end of the curve or another. With an infinite number of points you'll get the correct curve, but experiment with it to determine how finite you're willing to go.

I was also able to do this in OpenScad. The technique is the same. I was 3d printing a router template for rounding off corners of tables that used splines like this so it wasn't as obvious where the corners started and ended. I think ~40 points was accurate enough for me, but I was hitting the corner with sandpaper afterwards.

Thanks! I'll definitely give that a go when I get to that point.

Like I said, arcs are next (once I finish a re-write as a "Literate Program", 'cause managing stuff spread across three files has gotten to be a pain. I'm going to try the docmfp package as something straight-forward enough for me to wrap my mind around and which I can use on pretty much any computer I'm inclined to.