I have points list and control points list to draw a Bezier curve.
Please let me know how to calculate the boundary rectangle of the Bezier curve.
var pointsList = [CGPoint(34, 23), ... , CGPoint(23, 85)]
var controlPoints = [CGPoint(45, 34), ..., CGPoint(55, 99)]
Normally not really a hard problem, covered over on http://pomax.github.io/bezierinfo/#boundingbox:
Compute the x and y derivatives, which is super easy to do,
Find all roots (derivative=0) for both derivatives, let's call those the sets r{x} and r{y}, then
Compute the corresponding value sets bezier{x} and bezier{y} for those roots. Then,
Your bounding box has corners defined by the lowest and highest values min/max values in those sets.
In this, only step 2 might be a bit tricky if you're using high order bezier curves. Once your curve consists of more than four points, you can't use symbolic maths to find the roots and it's far easier to just run through the derivative curve and see where the resulting coordinates have a value close enough to zero to treat them as approximate root.
Your graphic looks like it's simply a series of connected cubic Bezier curves, in which case the root finding is easy (the derivatives will be quadratic curves, you learn how to find the roots for those in high school using the quadratic equation), and the box procedure is simply "compute the bounding box for each cubic curve section, and when you're done, the full bounding box simply uses the min/max values across all individual boxes".
Related
I am trying to find the the sharp corners of a NURBS curve. For this problem I define a limit curvature. I am trying to find the sections on the curve that has a curvature higher then this value. One option is to interpolate over the curve and calculate curvature for all values but it may take time and some sharp points are likely to be missed. Any ideas about how to find these sections in an effective way?
Computing the derivative of the curvature analytically, I guess that you will find a (terrible) expression with a polynomial at the numerator. A good polynomial solver will allow you to find the roots, hence the extrema, to split the curve in sections with a monotonic curvature, and from there find the precise solutions of k=c by regula falsi or similar.
A much simpler approach is by flattening the curve (convert to a smooth polyline) and estimating the local curvature on all triples of consecutive points (using their circumscribed circle). High curvature sections will probably also be detectable by anomalies in the point density while flattening.
The benefit of flattening over uniform sampling is that it auto-adjusts the point density.
Another idea is to resort to a method of approximation of curves by circular arcs (this can be compared to a second order flattening operation). You will find a few papers on the topic (do not confuse with circle approximation by curves), but usually these methods are complex.
Maybe it is also possible to devise an analytic formula for a lower bound on the NURBS curvature in a given interval and use that to implement a bisection approach.
How do I compute the control points given a curve in the form of power form? Say I have p(t)=(x(t),y(t)) and 4 control points.
x(t) = 2t
y(t) = (t^3)+3(t^2)
You can always convert from power basis to Bernstein basis. This is always doable and will give you the precise result. Refer to section 3.3 of this link (http://cagd.cs.byu.edu/~557/text/ch3.pdf) for details.
EDIT:
Since the above link is no longer available, I am listing the formula below:
where M is the degree of the Berstein basis, 0 <= k <= M and b_i,k=0 if i < k.
Using the common cubic Berstein basis (where M=3) as an example, we will have
this is pure math question (unless you go for the #3)... I am deducing you need 4 control points for single cubic Bezier curve in 2D.
algebraic approach
try to match your x(t),y(t) polynomials to Bezier polynomials form and extract the coefficients/control points. This is not always doable but most precise... see the link in #2 at the end I do this for my interpolation polynomial to match the Bezier so I get the conversion formula between control points.
interpolation
find extreme points on your curve (to preserve precision as much as possible) if none or not enough extremes found use equally dispersed points along curve for the rest. You need 4 control points on the curve. Now just convert these 4 points to curve for example by this: how to convert interpolation cubic polynmial to cubic Bezier
can use curve fitting
either use approximation search or any other minimization of curves distance ... by fitting Bezier control points but that is 8 parameters to search for which is slow and non precise without additional constrains ..
I am sure there are a lot more (possibly hybrid) methods out there for this problem.
I am developing a 3D graphic application in which the user can draw curves.
I record the curve that is drawn by the user and i would like to create a smooth nurb from the recorded set of points.
I tried using the openNurbs library but i could not find a way to do the fitting using the library.
How can i fit a set of points to a nurb?
First of all, I don't think you need nurbs. Fitting a B-spline curve to your data points should be good enough.
If you only have a few dozen points, then it is likely you would like the B-spline curve to exactly pass thru these data points. In this case, you are looking for spline interpolation algorithms. If this is the case, you can use Catmull Rom spline or Overhauser spline to interpolate your data points. Both will create C1 cubic splines and both are easy to implement without the need to solve a linear equation set.
If you have several hundreds of points, then it is likely that you only want the B-spline curve to lie close to the data points. Then, the algorithm you are looking for is least square fitting. You can find plenty of articles (e.g.: link1 ) in this area online. A typical algorithm for least square fitting with B-spline curve will involve these steps:
1) Choose a parametrization for your data points. Chord length parametrization is typically a good choice for least square fitting.
2) Choose the degree for the B-spline. Typically, we use degree 3, i.e., cubic B-spline.
3) Decide number of control points for your B-spline.
4) Decide the knot vector based on the information in the first 3 steps.
5) Solve a linear equation set to find the control points of the B-spline.
Is it possible to calculate intermediate points of a curve...Here is my mirror image
In the above image.Is it possible to calculate the intermediate points(one side) by knowing starting and ending point
If you know something about the curve it is, and it all depends on what you know about the curve (start and end points, initial slopes, center points, etc). There are generally two approaches:
If you know the equation of the curve, it's possible to do this exactly. Commonly curves like this are either circles or Bezier curves, and if you know it's either of these, you can fit all the other points exactly just given a few.
You can also do a cubic spline fit. This is a standard approach to fitting smooth curves so packages to do this are very common. On a smooth curve like this, give then end points, and, say, the middle point, the fit will be almost exact. (Here, you essentially end up with a Bezier curve, though parametrized a bit differently.)
I'll apologize in advance in case this is obvious; I've been unable to find the right terms to put into Google.
What I want to do is to find a bounding volume (AABB is good enough) for an arbitrary parametric range over a trimmed NURBS surface. For instance, (u,v) between (0.1,0.2) and (0.4,0.6).
EDIT: If it helps, it would be fine for me if the method confined the parametric region entirely within a bounding region as defined in the paragraph below. I am interested in sub-dividing those regions.
I got started thinking about this after reading this paragraph from this paper ( http://www.cs.utah.edu/~shirley/papers/raynurbs.pdf ), which explains how to create a tree of bounding volumes with a depth relative to the degree of the surface:
The convex hull property of B-spline surfaces guarantees that the surface is contained in the convex hull of its control mesh.
As a result, any convex objects which bound the mesh will bound the underlying surface. We can actually make a stronger
claim; because we closed the knot intervals in the last section [made the multiplicity of the internal knots k − 1], each nonempty
interval [ui; ui+1) [vj; vj+1) corresponds to a surface patch which is completely contained in the convex hull of
its corresponding mesh points. Thus, if we produce bounding volumes for each of these intervals, we will have completely
enclosed the surface. We form the tree by sorting the volumes according tothe axis direction which has greatest extent across the bounding volumes, splitting the data in half, and repeating the process.
Thanks! Sean
You will need to slice out a smaller NURBS surface, which only covers the parameter range you are interested in. Using your example, which I take to mean you are in the region where the u parameter is between 0.1 and 0.4. Let Pu be the degree of the spline in that parameter (A cubic spline has Pu = 3). You need to perform "knot insertion" (There's your Google search term) to get knots of degree Pu located at u=0.1 and u=0.4 Do the same thing on the v parameter to get knots of degree Pv at 0.2 and 0.6. The process of knot insertion will modify (and add to) the array of control points. There's a bit of bookkeeping involved, but you can then find the control_points that determine the surface in the parameter patch you just isolated between inserted knots. The convex property then says the surface is bounded by these control points, so you can use them to determine your bounding volume.
The NURBS reference I like to use for operations like this is: "The NURBS Book", by Les Piegl and Wayne Tiller.