number of control points for B spline curve - curve-fitting

I am trying to use B spline curve fitting. The order of B spline curve is 4. When I have many control points, it works well. However if the number of control points is small such as two, my program will crash. I realize that the number of control points is related to number of knots and the order. Can anyone help me clarify the relationship or give some links on it?

Sounds like you're simply reading out of bounds, which is not a specific issue of calculating splines. To calculate a b-spline of degree n, you'll need at least n + 1 points.
To simplify and show the issue:
The easiest way of interpolation is linear interpolation - just draw a line between two points.
If you've got only one point, you can't interpolate anything, simply due to the fact that you don't know where to draw.
For a quadratic interpolation, you'll need at least three points, etc.
In a similar way, you'll need at least 5 points for a b-spline of 4th degree.
A really nice online demo can be found here:
Pick any b-spline demo on the lower left side, I'd just go for the linear one.
On the right you're now able to set the number of control points as well as the degree of the curve.
Feel free to try around, also by moving the points around with your mouse.

Two control points is not sufficient to define a B-spline of order 4. For B-splines, the number of knots needs to equal the sum of number of control points and order. A single segment degree 3 B-spline will require 4 control points and 8 knot values. So, to calculate a B-spline with order N, you at least need N points. That will give you a B-spline with single segment. If you have more points, then the resulting B-spline will have more segments.

As others stated, the number of control points is equal to the number of knots minus the order of the bspline basis. Thus you cannot have an arbitrary combination of order, say k, and knot vector for your bspline function/curve once you fix the control points.
A very useful link for theory on b-splines and nurbs curves is the following:
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/index.html
There you can find the relationship of number of control points with dimensionality of knot vector etc as well as detailed examples and some algorithms.
Depending on your needs, you may also wish to check "The NURBS book" by Piegl and Tiller
http://www.amazon.com/NURBS-Book-Monographs-Visual-Communication/dp/3540615458
they have done an amazing job and in their book they include working algorithms.
The curve fitting problem of a b-spline to data is a rather large subject since you have to take care to avoid over/under fitting. There are several approaches, and most involve including a curvature penalty term. The literature is vast, but you can find a lot of information and a great starting point in the book by Hastie et. al. "The elements of statistical learning" which you can legally download from the authors site:
http://statweb.stanford.edu/~tibs/ElemStatLearn/
The curve fitting problem is covered to some extent in all references I gave. Good luck.

Related

How to break a geometry into blocks?

I am certain there is already some algorithm that does what I need, but I am not sure what phrase to Google, or what is the algorithm category.
Here is my problem: I have a polyhedron made up by several contacting blocks (hyperslabs), i. e. the edges are axis aligned and the angles between edges are 90°. There may be holes inside the polyhedron.
I want to break up this concave polyhedron in as little convex rectangular axis-aligned whole blocks are possible (if the original polyhedron is convex and has no holes, then it is already such a block, and therefore, the solution). To illustrate, some 2-D images I made (but I need the solution for 3-D, and preferably, N-D):
I have this geometry:
One possible breakup into blocks is this:
But the one I want is this (with as few blocks as possible):
I have the impression that an exact algorithm may be too expensive (is this problem NP-hard?), so an approximate algorithm is suitable.
One detail that maybe make the problem easier, so that there could be a more appropriated/specialized algorithm for it is that all edges have sizes multiple of some fixed value (you may think all edges sizes are integer numbers, or that the geometry is made up by uniform tiny squares, or voxels).
Background: this is the structured grid discretization of a PDE domain.
What algorithm can solve this problem? What class of algorithms should I
search for?
Update: Before you upvote that answer, I want to point out that my answer is slightly off-topic. The original poster have a question about the decomposition of a polyhedron with faces that are axis-aligned. Given such kind of polyhedron, the question is to decompose it into convex parts. And the question is in 3D, possibly nD. My answer is about the decomposition of a general polyhedron. So when I give an answer with a given implementation, that answer applies to the special case of polyhedron axis-aligned, but it might be that there exists a better implementation for axis-aligned polyhedron. And when my answer says that a problem for generic polyhedron is NP-complete, it might be that there exists a polynomial solution for the special case of axis-aligned polyhedron. I do not know.
Now here is my (slightly off-topic) answer, below the horizontal rule...
The CGAL C++ library has an algorithm that, given a 2D polygon, can compute the optimal convex decomposition of that polygon. The method is mentioned in the part 2D Polygon Partitioning of the manual. The method is named CGAL::optimal_convex_partition_2. I quote the manual:
This function provides an implementation of Greene's dynamic programming algorithm for optimal partitioning [2]. This algorithm requires O(n4) time and O(n3) space in the worst case.
In the bibliography of that CGAL chapter, the article [2] is:
[2] Daniel H. Greene. The decomposition of polygons into convex parts. In Franco P. Preparata, editor, Computational Geometry, volume 1 of Adv. Comput. Res., pages 235–259. JAI Press, Greenwich, Conn., 1983.
It seems to be exactly what you are looking for.
Note that the same chapter of the CGAL manual also mention an approximation, hence not optimal, that run in O(n): CGAL::approx_convex_partition_2.
Edit, about the 3D case:
In 3D, CGAL has another chapter about Convex Decomposition of Polyhedra. The second paragraph of the chapter says "this problem is known to be NP-hard [1]". The reference [1] is:
[1] Bernard Chazelle. Convex partitions of polyhedra: a lower bound and worst-case optimal algorithm. SIAM J. Comput., 13:488–507, 1984.
CGAL has a method CGAL::convex_decomposition_3 that computes a non-optimal decomposition.
I have the feeling your problem is NP-hard. I suggest a first step might be to break the figure into sub-rectangles along all hyperplanes. So in your example there would be three hyperplanes (lines) and four resulting rectangles. Then the problem becomes one of recombining rectangles into larger rectangles to minimize the final number of rectangles. Maybe 0-1 integer programming?
I think dynamic programming might be your friend.
The first step I see is to divide the polyhedron into a trivial collection of blocks such that every possible face is available (i.e. slice and dice it into the smallest pieces possible). This should be trivial because everything is an axis aligned box, so k-tree like solutions should be sufficient.
This seems reasonable because I can look at its cost. The cost of doing this is that I "forget" the original configuration of hyperslabs, choosing to replace it with a new set of hyperslabs. The only way this could lead me astray is if the original configuration had something to offer for the solution. Given that you want an "optimal" solution for all configurations, we have to assume that the original structure isn't very helpful. I don't know if it can be proven that this original information is useless, but I'm going to make that assumption in this answer.
The problem has now been reduced to a graph problem similar to a constrained spanning forest problem. I think the most natural way to view the problem is to think of it as a graph coloring problem (as long as you can avoid confusing it with the more famous graph coloring problem of trying to color a map without two states of the same color sharing a border). I have a graph of nodes (small blocks), each of which I wish to assign a color (which will eventually be the "hyperslab" which covers that block). I have the constraint that I must assign colors in hyperslab shapes.
Now a key observation is that not all possibilities must be considered. Take the final colored graph we want to see. We can partition this graph in any way we please by breaking any hyperslab which crosses the partition into two pieces. However, not every partition is meaningful. The only partitions that make sense are axis aligned cuts, which always break a hyperslab into two hyperslabs (as opposed to any more complicated shape which could occur if the cut was not axis aligned).
Now this cut is the reverse of the problem we're really trying to solve. That cutting is actually the thing we did in the first step. While we want to find the optimal merging algorithm, undoing those cuts. However, this shows a key feature we will use in dynamic programming: the only features that matter for merging are on the exposed surface of a cut. Once we find the optimal way of forming the central region, it generally doesn't play a part in the algorithm.
So let's start by building a collection of hyperslab-spaces, which can define not just a plain hyperslab, but any configuration of hyperslabs such as those with holes. Each hyperslab-space records:
The number of leaf hyperslabs contained within it (this is the number we are eventually going to try to minimize)
The internal configuration of hyperslabs.
A map of the surface of the hyperslab-space, which can be used for merging.
We then define a "merge" rule to turn two or more adjacent hyperslab-spaces into one:
Hyperslab-spaces may only be combined into new hyperslab-spaces (so you need to combine enough pieces to create a new hyperslab, not some more exotic shape)
Merges are done simply by comparing the surfaces. If there are features with matching dimensionalities, they are merged (because it is trivial to show that, if the features match, it is always better to merge hyperslabs than not to)
Now this is enough to solve the problem with brute force. The solution will be NP-complete for certain. However, we can add an additional rule which will drop this cost dramatically: "One hyperslab-space is deemed 'better' than another if they cover the same space, and have exactly the same features on their surface. In this case, the one with fewer hyperslabs inside it is the better choice."
Now the idea here is that, early on in the algorithm, you will have to keep track of all sorts of combinations, just in case they are the most useful. However, as the merging algorithm makes things bigger and bigger, it will become less likely that internal details will be exposed on the surface of the hyperslab-space. Consider
+===+===+===+---+---+---+---+
| : : A | X : : : :
+---+---+---+---+---+---+---+
| : : B | Y : : : :
+---+---+---+---+---+---+---+
| : : | : : : :
+===+===+===+ +---+---+---+
Take a look at the left side box, which I have taken the liberty of marking in stronger lines. When it comes to merging boxes with the rest of the world, the AB:XY surface is all that matters. As such, there are only a handful of merge patterns which can occur at this surface
No merges possible
A:X allows merging, but B:Y does not
B:Y allows merging, but A:X does not
Both A:X and B:Y allow merging (two independent merges)
We can merge a larger square, AB:XY
There are many ways to cover the 3x3 square (at least a few dozen). However, we only need to remember the best way to achieve each of those merge processes. Thus once we reach this point in the dynamic programming, we can forget about all of the other combinations that can occur, and only focus on the best way to achieve each set of surface features.
In fact, this sets up the problem for an easy greedy algorithm which explores whichever merges provide the best promise for decreasing the number of hyperslabs, always remembering the best way to achieve a given set of surface features. When the algorithm is done merging, whatever that final hyperslab-space contains is the optimal layout.
I don't know if it is provable, but my gut instinct thinks that this will be an O(n^d) algorithm where d is the number of dimensions. I think the worst case solution for this would be a collection of hyperslabs which, when put together, forms one big hyperslab. In this case, I believe the algorithm will eventually work its way into the reverse of a k-tree algorithm. Again, no proof is given... it's just my gut instinct.
You can try a constrained delaunay triangulation. It gives very few triangles.
Are you able to determine the equations for each line?
If so, maybe you can get the intersection (points) between those lines. Then if you take one axis, and start to look for a value which has more than two points (sharing this value) then you should "draw" a line. (At the beginning of the sweep there will be zero points, then two (your first pair) and when you find more than two points, you will be able to determine which points are of the first polygon and which are of the second one.
Eg, if you have those lines:
verticals (red):
x = 0, x = 2, x = 5
horizontals (yellow):
y = 0, y = 2, y = 3, y = 5
and you start to sweep through of X axis, you will get p1 and p2, (and we know to which line-equation they belong ) then you will get p3,p4,p5 and p6 !! So here you can check which of those points share the same line of p1 and p2. In this case p4 and p5. So your first new polygon is p1,p2,p4,p5.
Now we save the 'new' pair of points (p3, p6) and continue with the sweep until the next points. Here we have p7,p8,p9 and p10, looking for the points which share the line of the previous points (p3 and p6) and we get p7 and p10. Those are the points of your second polygon.
When we repeat the exercise for the Y axis, we will get two points (p3,p7) and then just three (p1,p2,p8) ! On this case we should use the farest point (p8) in the same line of the new discovered point.
As we are using lines equations and points 2 or more dimensions, the procedure should be very similar
ps, sorry for my english :S
I hope this helps :)

Algorithm for making straight lines out of bumpy pixels

The Problem:
I have an image that I downloaded from google's static map api. I use this image to basically create a "magic wand" type feature where a user clicks. For those interested I am using the graph cut algorithm to find the shape that the user clicked. I then find all the points that represent the border of this shape (borderPoints) using contour tracing.
My Goal:
Straighten out the lines (if possible) and minimize the amount of borderPoints (as much as possible). My current use case are the roofs of houses so in the majority of cases I would hope that I could find the corners and just use those as the borderPoints instead of all the varying points in between. But I am having trouble figuring out how to find those corners because of the bumpy pixel lines.
My Attempts at a Solution:
One simple technique is to loop over the points checking the point before, the current point, and the point after. If the point before and the point after have the same x or the same y then the current point can be removed. This trims the number of points down a little but not as much as I would like.
I also tried looking at the before and after point to see if the current point could be removed if it wasn't within a certain slope range but had little success because occasionally a key corner point was removed because the image was kind of fuzzy and the corner had slightly rounded points.
My Question:
Are there any algorithms for doing this type of thing? If so, what is it (they) called? If not, any thoughts on how to progamatically approach this problem?
This sounds similar to the Ramer–Douglas–Peucker algorithm. You may be able to do better by exploiting the fact that all your points lie on a grid.
Seems to me like you are looking for a polynomial approximation of degree 1.
For a quick answer to your question, you may want to read this: http://en.wikipedia.org/wiki/Simple_regression. The Numerical example section shows you concretely how the equation for your line can be computed.
Polynomial approximations allow you to approach a function, curve, group of point, however you want to call it with a polynomial function of the form an.x^n + ... + a1.x^1 + a0
In your case, you want a line, so you want a function a1.x + a0 where a1 and a0 will be calculated to minimize the error with the set of points you have.
There are various ways of computing your error (called a norm) and minimizing it. You may be interested for example in finding the line that minimizes the distance to any of the points you have (minimizing the max), or in minimizing the distance to the set of points as a whole (minimizing the sum of absolute differences, or the sum of squares of differences, etc.)
In terms of algorithms, you may want to look at Chebyshev approximations and Remez algorithms specifically. All of these solve the approximation of a function with a polynomial of any degree but in your case you will only care about degree 1.

Looking for a "closing curves connecting with respect to points" algorithm

I am looking for an algorithm that can connect points together with a continuous curve line. Imagine drawing from point a to b to c until the last point, and when you draw from point to point, the line must be a curve and is continuous with respect to the previous point and next point, as if the given points are just samples of a closed loop. Please see figure below for illustration.
Are there such algorithm for something like this?
*The circles in the figure are my list of points.
Given that your points are ordered, spline interpolation is definitely the best way to go here. (As indicated by by bo1024's comment) I highly recommend the following notes:
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/
And specifically the section here would be most relevant to getting a closed loop like you asked for:
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-closed.html
EDIT: If the curve has to pass through the points, then the unique degree n solution is the Lagrange interpolating polynomial. You can just make one polynomial for each component of your points vectors using the formula on the wiki page:
http://en.wikipedia.org/wiki/Lagrange_polynomial
Unfortunately Lagrange interpolation can be pretty noisy if you have too many points. As a result, I would still recommend using some fixed degree spline interpolation. Instead of B-splines, another option are Hermite polynomials:
http://en.wikipedia.org/wiki/Cubic_Hermite_spline
These will guarantee that the curve passes through the points. To get a closed curve, you need to repeat the the first d points of your curve when solving for the coefficients, where d is the degree of the Hermite spline you are using to approximate your points.
The problem is very similar to the travelling salesman problem, you may be able to extend some of the algorithms used to solve it to suit your case.
For instance, evolutionary algorithms are easy to adapt and you will find lot of references about using them to solve the TSP.

Reverse engineering a bezier curve

Given a few sample points on a bézier curve, is it possible to work out the set of possible curves these points may lie on?
In my specific application there is a limited set of endpoints the curve may have, so I want to generate the set of possible curves, enumerate all of them and pick out all the ones which may end on a valid end point.
Some people have asked for more detail.
I have a set of points which I know are on a quadratic bezier curve, I want to calculate the formula of the curve and be able to extrapolate new points on the curve.
Bezier curves will always go through starting and ending control points.
If the degree of the curve is equal to the number of sample points then there will be only one curve that will pass through all your points (in a normal case, where all points are different and they don't lie on a bezier curve of a lesser degree).
If the degree of a curve is less then the number of the sample points then, in general case, you will not be able to make the curve go through all the points (in a normal case).
If the degree of a curve is higher then the number of the sample points then, in general case, you will be able to draw infinite number of curves.
In the wiki article you will find references to control points only, but still I believe that I remember the above properties correctly and that they hold for the points on the curves as well.
I think you need to redefine your question and exactly define what type of curves (and of which degree) do you need. Also as Georg pointed out you might be looking for paths - a combination of curves.
EDIT:
First a correction - curve is defined with degree plus one number of control points points (quadratic need three). Control points are not the same as points on the curve - and for three points on the curve and quadratic curve you could have infinite number of solutions (see this for quadratic curve and four points)
As for the solution (but still under assumption that you are looking at a single curve):
For an equation for single quadratic curve you have
B(t) = (1-t)^2*P0 + 2*(1-t)*t*P1 + t^2*P2
Capital letters above are vectors, and P0 corresponds to starting control point (first point), P2 corresponds to ending control point (last point), so you still need to find P1. The variable t is scalar that ranges from 0 to 1.
If working with 2D curves the above vector equation gives two scalar equations for each point on the curve.
Still there is t as an unknown, so you should take 2 more points (4 in total) which will give you 4 unknowns (t for first point, t for second point, x and y of the P1, middle control point) and 4 equation to solve (2 from each sample point).
Solve that with your favourite numerical method and you will get the original curve on which the points came from.
If you still think that you can get more curves and that you will have to choose something then you are not working with bezier curves, but with bezier splines (in a sense of multiple curves joined together). Still the same principle applies and if you work out a way to solve a single curve from the above equations (and if you have enough points) then you can divide the problem into n-segments of actual bezier curves and solve each as outlined above.
If it turns out that you don't have enough points then look at the linked article again - you are probably looking for the smoothest curve and there are some suggestions in the article on how to get there as looking for the exact solution (shortest curve/smoothest curve) seems to be rather complex.

Is there an efficient algorithm to generate a 2D concave hull?

Having a set of (2D) points from a GIS file (a city map), I need to generate the polygon that defines the 'contour' for that map (its boundary). Its input parameters would be the points set and a 'maximum edge length'. It would then output the corresponding (probably non-convex) polygon.
The best solution I found so far was to generate the Delaunay triangles and then remove the external edges that are longer than the maximum edge length. After all the external edges are shorter than that, I simply remove the internal edges and get the polygon I want. The problem is, this is very time-consuming and I'm wondering if there's a better way.
One of the former students in our lab used some applicable techniques for his PhD thesis. I believe one of them is called "alpha shapes" and is referenced in the following paper:
http://www.cis.rit.edu/people/faculty/kerekes/pdfs/AIPR_2007_Gurram.pdf
That paper gives some further references you can follow.
This paper discusses the Efficient generation of simple polygons for characterizing the shape of a set of points in the plane and provides the algorithm. There's also a Java applet utilizing the same algorithm here.
The guys here claim to have developed a k nearest neighbors approach to determining the concave hull of a set of points which behaves "almost linearly on the number of points". Sadly their paper seems to be very well guarded and you'll have to ask them for it.
Here's a good set of references that includes the above and might lead you to find a better approach.
The answer may still be interesting for somebody else: One may apply a variation of the marching square algorithm, applied (1) within the concave hull, and (2) then on (e.g. 3) different scales that my depend on the average density of points. The scales need to be int multiples of each other, such you build a grid you can use for efficient sampling. This allows to quickly find empty samples=squares, samples that are completely within a "cluster/cloud" of points, and those, which are in between. The latter category then can be used to determine easily the poly-line that represents a part of the concave hull.
Everything is linear in this approach, no triangulation is needed, it does not use alpha shapes and it is different from the commercial/patented offering as described here ( http://www.concavehull.com/ )
A quick approximate solution (also useful for convex hulls) is to find the north and south bounds for each small element east-west.
Based on how much detail you want, create a fixed sized array of upper/lower bounds.
For each point calculate which E-W column it is in and then update the upper/lower bounds for that column. After you processed all the points you can interpolate the upper/lower points for those columns that missed.
It's also worth doing a quick check beforehand for very long thin shapes and deciding wether to bin NS or Ew.
A simple solution is to walk around the edge of the polygon. Given a current edge om the boundary connecting points P0 and P1, the next point on the boundary P2 will be the point with the smallest possible A, where
H01 = bearing from P0 to P1
H12 = bearing from P1 to P2
A = fmod( H12-H01+360, 360 )
|P2-P1| <= MaxEdgeLength
Then you set
P0 <- P1
P1 <- P2
and repeat until you get back where you started.
This is still O(N^2) so you'll want to sort your pointlist a little. You can limit the set of points you need to consider at each iteration if you sort points on, say, their bearing from the city's centroid.
Good question! I haven't tried this out at all, but my first shot would be this iterative method:
Create a set N ("not contained"), and add all points in your set to N.
Pick 3 points from N at random to form an initial polygon P. Remove them from N.
Use some point-in-polygon algorithm and look at points in N. For each point in N, if it is now contained by P, remove it from N. As soon as you find a point in N that is still not contained in P, continue to step 4. If N becomes empty, you're done.
Call the point you found A. Find the line in P closest to A, and add A in the middle of it.
Go back to step 3
I think it would work as long as it performs well enough — a good heuristic for your initial 3 points might help.
Good luck!
You can do it in QGIS with this plug in;
https://github.com/detlevn/QGIS-ConcaveHull-Plugin
Depending on how you need it to interact with your data, probably worth checking out how it was done here.
As a wildly adopted reference, PostGIS starts with a convexhull and then caves it in, you can see it here.
https://github.com/postgis/postgis/blob/380583da73227ca1a52da0e0b3413b92ae69af9d/postgis/postgis.sql.in#L5819
The Bing Maps V8 interactive SDK has a concave hull option within the advanced shape operations.
https://www.bing.com/mapspreview/sdkrelease/mapcontrol/isdk/advancedshapeoperations?toWww=1&redig=D53FACBB1A00423195C53D841EA0D14E#JS
Within ArcGIS 10.5.1, the 3D Analyst extension has a Minimum Bounding Volume tool with the geometry types of concave hull, sphere, envelope, or convex hull. It can be used at any license level.
There is a concave hull algorithm here: https://github.com/mapbox/concaveman

Resources