ccBezierConfig as a quadratic, not cubic. - objective-c

So I'm trying to animate a sprite, and I just found the CCBezierBy/CCBezierTo methods, which are saving me a lot of trouble, but they only work as cubic functions.
HOw can I make them quadratics? (I need s-curves)
Having only 3 controlpoints limits severely what you can do.
Thank you.

I don't think you understand Bezier curves here: S curves cannot be modeled by quadratic Beziers, they can only do curves with a single inflection point. Cubic curves can have two inflection points, so quadratic curves can only model curves that look like | or C, and cubic curves can model anything that looks like |, C or S
Cubic functions have a starting on-curve point, two control points, and an ending on-curve point, for a total of four control points; Quadratic functions have a starting on-curve point, one control point, and an ending on-curve point, for a total of three control points.
So what you want is a cubic curve, and that's exactly what the CCBezierBy/CCBezierTo methods offer. They let you specify a bezier curve as the two control points and end point, because you'll already have the starting point.

Related

Splitted Bezier curve

Suppose I splitted a cubic bezier curve at the point corresponding to the parameter t=0.5. Call the splitted parts C and D. Then I connect ends of C by a straight line segment. Can we say that this straight line segment never touches C apart from the endpoints?
No. This is because the split portion C and D are also a cubic Bezier curve, which can be of any shape (that a cubic polynomial curve can be). A straight line connecting two ends of a cubic Bezier curve could have intersected the curve at the interior if the cubic Bezier curve is not convex.
If you want to produce an example, you will have to make the control points going up and down drastically as shown in the following example (where the green dots are control points and the yellow dot is where t=0.5).
A close-up on where t=0.5 shows
No, because as I understand it, a straight line is a degenerate case of a Bezier curve.
So you would need to ensure, for example, that the control points are not on the line.
If the also happens to be that both points are on the same side of the line (e.g. either both above, both below, both to the left or both to the right), then that would do it.
If you don't have the control points, but have two points near the endpoints of the line, you can do the same test.
Or in other words the case where you might need to worry about is when either the control points or points near the endpoints are on in different side of the line between the endpoints.

Bezier Curve parameter and the distance taken

For a cubic bezier curve, if its parameter t is 0.5 then does this split the curve equal pieces lengthwise? Reasoning is appreciated.
In general, no, unless in some special cases, for example all control points of the cubic Bezier curve are collinear and evenly-spaced. The reason is simple: a Bezier curve is in general not arc-length parameterized.
Simple example: take three 2D control points
(1,0), (2,0) and (4,0)
The point t=0.5 is (2,0). But this point does not have equal distances to the first and last point.
Well, and this should not depend on the cubic or linear case.

How to choose control point distance for 3D cubic Bézier curves to optimize 'roundness'?

Say I want to construct a 3D cubic Bézier curve, and I already have both end-points, and the direction (normal vector) for both control points. How can I choose the distance of both control points to their respective end-points in order to make the curve as 'nicely rounded' as possible?
To formalize 'nicely rounded': I think that means maximizing the smallest angle between any two segments in the curve. For example, having end-points (10, 0, 0) and (0, 10, 0) with respective normal vectors (0, 1, 0) and (1, 0, 0) should result in a 90° circular arc. For the specific case of 2D circular arcs, I've found articles like this one. But I haven't been able to find anything for my more general case.
(Note that these images are just to illustrate the 'roundness' concept. My curves are not guaranteed to be plane-aligned. I may replace the images later to better illustrate that point.)
This is a question of aesthetics, and if the real solution is unknown or too complicated, I would be happy with a reasonable approximation. My current approximation is too simplistic: choosing half the distance between the two end-points for both control point distances. Someone more familiar with the math will probably be able to come up with something better.
(PS: This is for open-source software, and I would be happy to give credit on GitHub.)
Edit: Here are some other images to illustrate a 3D case (jsfiddle):
Edit 2: Here's a screenshot of an unstable version of ApiNATOMY to give you an idea of what I'm trying to do. I'm creating 3D tubes to represent blood-vessels, connecting different parts of an anatomical schematic:
(They won't let me put in a jsfiddle link if I don't include code...)
What you are basically asking is to have curvature over the spline as constant as possible.
A curve with constant curvature is just a circular arc, so it makes sense to try to fit such an arc to your input parameters. In 2D, this is easy: construct the line which goes through your starting point and is orthogonal to the desired direction vector. Do the same for the ending point. Now intersect these two lines: the result is the center of the circle which passes through the two points with the desired direction vectors.
In your example, this intersection point would just be (0,0), and the desired circular arc lies on the unit circle.
So this gives you a circular arc, which you can either use directly or use the approximation algorithm which you have already cited.
This breaks down when the two direction vectors are collinear, so you'd have to fudge it a bit if this ever comes up. If they point at each other, you can simply use a straight line.
In 3D, the same construction gives you two planes passing through the end points. Intersect these, and you get a line; on this line, choose the point which minimizes the sum of squared distances to the two points. This gives you the center of a sphere which touches both end points, and now you can simply work in the plane spanned by these three points and proceed as in 2D.
For the special case where your two end points and the two known normal vector for the control points happen to make the Bezier curve a planar one, then basically you are looking for a cubic Bezier curve that can well approximate a circular arc. For this special case, you can set the distance (denoted as L) between the control point and their respective end point as L = (4/3)*tan(A/4) where A is the angle of the circular arc.
For the general 3D case, perhaps you can apply the same formula as:
compute the angle between the two normal vectors.
use L=(4/3)*tan(A/4) to decide the location of your control points.
if your normals are aligned in a plane
What you're basically doing here is creating an elliptical arc, in 3D, where the "it's in 3D" part is completely irrelevant, since it's just a 2D curve, rotated/translated to sit in your 3D space. So let's just solve the 2D case, and then the RT is entirely up to you.
Creating the "perfect" cubic Bezier between two points on an arc comes with limitations. You basically can't create good looking arcs that span more than a quarter circle. So, with that said: your start and end point normals give you a 2D angle between your normal vectors, which is the same angle as between your start and end tangents (since normals are perpendicular to tangents). So, let's:
align our curve so that the tangent at the start is 0
plug the angle between tangents into the formula given in the section on Circle approximation in the Primer on Bezier curves. This is basically just dumb "implementing the formula for c1x/c1y/c2x/c2y as a function that takes an angle as argument, and spits out four values as c1(x,y) and c2(x,y) coordinats".
There is no step 3, we're done.
After step 2, you have your control points in 2D to create the most circular arc between a start and end point. Now you just need to scale/rotate/translate it in 3D so that it lines up with where you needed your start and end point to begin with.
if your normals are not aligned in a plane
Now we have a problem, although one that we can deal with by treating the dimensions as separate things entirely. Instead of creating a single 2D curve, we're going to create three: one that's the X/Y projection, one that's the X/Z projection, and one that's the Y/Z projection. For all three of these, we're going to abstract the control points in exactly the same way as before, and then we simply take the projective control points (three for each control point), and then go "okay, we now have X, Y, and Z projective coordinates. That means we have (X,Y,Z) coordinates", and done again.

Equation for Length of Cubic Spline Between 3 Points

This is my first time posting here, so I hope this is ok. I'm working on a java project but my question is really about the math I'll be using for it...
I have three (different) points at (x1, y1), (x2, y2), and (x3, y3). All I need is a formula for the length of the cubic spline formed between them. For someone good at calculus, this should be pretty easy to derive. I've looked all around online but can't seem to find the solution. Again, I don't even need the equation of the spline - just its length, given the three points. Thanks in advance! If someone can figure this out and share, you'll makey day :)
I have some bad news.
The first is that a cubic b-spline generally takes 4 points to define. It is possible to define one from 3 points, but it usually involves making up another point somehow (for example, using degree elevation). So we'd need to have information about how exactly you're defining the spline - if it's some other kind of spline (catmull-rohm?), or the details of how you're constructing it.
The second is that there's no closed-form equation for the length of a b-spline, or even a Bezier curve. What I typically do is sample the curve at a lot of points, and then compute the length of the polyline.
There are formulas that can tell you what your error bound will be, based on the derivatives of the curve, and there are methods that approximate using arcs rather than line segments, but those are probably more complicated than they're worth.
See the primer on bezier curves for a more info. However, sadly, tfinniga is correct for cubic splines you need to use an approximation.

Find bezier control-points for curve passing through N points

Considering the following nice solution for finding cubic Bézier control points for a curve passing through 4 points:
How to find control points for a BezierSegment given Start, End, and 2 Intersection Pts in C# - AKA Cubic Bezier 4-point Interpolation
I wonder, if there is a straightforward extension to this for making the Bézier curve pass through N points, for N > 2 and maybe N ≤ 20?
This is a really old question, but I'm leaving this here for people who have the same question in the future.
#divanov has mentioned that there's no Bezier curve passing through N arbitrary points for N >4.
I think the OP was asking how to compute the control points to join multiple bezier curves to produce a single curve that looks smooth.
This pdf will show you how to compute the control points: http://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf
which I found on this writeup https://developer.squareup.com/blog/smoother-signatures/ from Square about how they render a smooth curve that passes through all the sampled points of a mouse drawn signature.
In general, there is no Bezier curve passing through N arbitrary points, where N > 4. One should consider curve fitting to minimize least square error between computed Bezier curve and given N data points. Which is discussed, for example, here.