I'm writing a C++ program to generate a cubic spline trajectory for a set of points. These points need not be sorted along the x-axis. For example, it may be a circle, etc.
I have found some libraries on the web, for example, the ALGLIB library or a class here https://www.marcusbannerman.co.uk/index.php/home/42-articles/96-cubic-spline-class.html, but all of these libraries sort the data points. I do not need this because what I want to generate is something like a circle. Is there anyway to achieve this?
Splines are piecewise functions with respect to some independent variable (usually t, though they seem to use x in the code you have linked). Since the specific function to be evaluated depends on the control points closest to the input value t, it make sense to sort the control points by t so that you can quickly determine the function that needs to be evaluated.
However even if they were not sorted, you still could not create a circle with a single one dimensional spline. Your spline function y = f(t) only gives you one value for any given t. If you are graphing y with respect to t and want a circle with radius 1 about the origin, you would need f(0) to equal both 1 and -1, which doesn't make any sense.
To get something like a circle you instead need a two dimensional spline, or two splines; one for the x value and one for the y value. Once you have these two spline functions f(t) and g(t), then you simply evaluate both functions at the same t and that will give you the x and y values of your spline for that t.
The simple, common trick is to use cumulative linear arclength as the parameter. So, if I have a set of points in a curve as simply (x,y) pairs in the plane where x and y are vectors, do this:
t = cumsum([0;sqrt(diff(x(:)).^2 + diff(y(:)).^2)]);
This gives us the cumulative distance along the piecewise linear segments between each pair of points, presented in the order you have them. Fit the spline curve as two separate spline models, thus x(t) and y(t). So you could use interp1, or use the spline or pchip functions directly. Note that pchip and spline will have different properties when you build that interpolant.
Finally, in the event that you really had a closed curve, so that x(1) and x(end) were supposed to be the same, then you would really want to use a spline model with periodic end conditions. I don't know of any implementations for that except in the spline model in my SLM tools, but it is not difficult to do in theory.
Related
so I was reading on active contour and the equation doesn't really make much sense to me, I looked for other resources but none of the resources really explained this
what does the integral of the derivative of a squared function mean?
The derivative is the change of the function so if we want a smooth function we would want small changes along the function meaning a small derivative. A derivative of zero is a constant function which is the most smooth function that we can get.
We use the squared distance of the derivative (L2) and zero so we get the square.
In order to get a smooth function along the curve we would like that the sum of the change along the curve will be small. The sum is the integral of the derivative along the curve.
So, I have two points, say A and B, each one has a known (x, y) coordinate and a speed vector in the same coordinate system. I want to write a function to generate a set of arcs (radius and angle) that lead A to status B.
The angle difference is known, since I can get it by subtracting speed unit vector. Say I move a certain distance with (radius=r, angle=theta) then I got into the exact same situation. Does it have a unique solution? I only need one solution, or even an approximation.
Of course I can solve it by giving a certain circle and a line(radius=infine), but that's not what I want to do. I think there's a library that has a function for this, since it's quite a common approach.
A biarc is a smooth curve consisting of two circular arcs. Given two points with tangents, it is almost always possible to construct a biarc passing through them (with correct tangents).
This is a very basic routine in geometric modelling, and it is indispensable for smoothly approximating an arbirtrary curve (bezier, NURBS, etc) with arcs. Approximation with arcs and lines is heavily used in CAM, because modellers use NURBS without a problem, but machine controllers usually understand only lines and arcs. So I strongly suggest reading on this topic.
In particular, here is a great article on biarcs on biarcs, I seriously advice reading it. It even contains some working code, and an interactive demo.
I'm looking for interpolating some contour lines to generating a 3D view. The contours are not stored in a picture, coordinates of each point of the contour are simply stored in a std::vector.
for convex contours :
, it seems (I didn't check by myself) that the height can be easily calculates (linear interpolation) by using the distance between the two closest points of the two closest contours.
my contours are not necessarily convex :
, so it's more tricky... actualy I don't have any idea what kind of algorithm I can use.
UPDATE : 26 Nov. 2013
I finished to write a Discrete Laplace example :
you can get the code here
What you have is basically the classical Dirichlet problem:
Given the values of a function on the boundary of a region of space, assign values to the function in the interior of the region so that it satisfies a specific equation (such as Laplace's equation, which essentially requires the function to have no arbitrary "bumps") everywhere in the interior.
There are many ways to calculate approximate solutions to the Dirichlet problem. A simple approach, which should be well suited to your problem, is to start by discretizing the system; that is, you take a finite grid of height values, assign fixed values to those points that lie on a contour line, and then solve a discretized version of Laplace's equation for the remaining points.
Now, what Laplace's equation actually specifies, in plain terms, is that every point should have a value equal to the average of its neighbors. In the mathematical formulation of the equation, we require this to hold true in the limit as the radius of the neighborhood tends towards zero, but since we're actually working on a finite lattice, we just need to pick a suitable fixed neighborhood. A few reasonable choices of neighborhoods include:
the four orthogonally adjacent points surrounding the center point (a.k.a. the von Neumann neighborhood),
the eight orthogonally and diagonally adjacent grid points (a.k.a. the Moore neigborhood), or
the eight orthogonally and diagonally adjacent grid points, weighted so that the orthogonally adjacent points are counted twice (essentially the sum or average of the above two choices).
(Out of the choices above, the last one generally produces the nicest results, since it most closely approximates a Gaussian kernel, but the first two are often almost as good, and may be faster to calculate.)
Once you've picked a neighborhood and defined the fixed boundary points, it's time to compute the solution. For this, you basically have two choices:
Define a system of linear equations, one per each (unconstrained) grid point, stating that the value at each point is the average of its neighbors, and solve it. This is generally the most efficient approach, if you have access to a good sparse linear system solver, but writing one from scratch may be challenging.
Use an iterative method, where you first assign an arbitrary initial guess to each unconstrained grid point (e.g. using linear interpolation, as you suggest) and then loop over the grid, replacing the value at each point with the average of its neighbors. Then keep repeating this until the values stop changing (much).
You can generate the Constrained Delaunay Triangulation of the vertices and line segments describing the contours, then use the height defined at each vertex as a Z coordinate.
The resulting triangulation can then be rendered like any other triangle soup.
Despite the name, you can use TetGen to generate the triangulations, though it takes a bit of work to set up.
I'm currently studying lighting in OpenGL, which utilizes a function in GLSL called normalize. According to OpenGL docs, it says that it "calculates the normalized product of two vectors". However, it still doesn't explain what "normalized" mean. I have tried look for what a normalized product is on Google, however I can't seem to find anything about it. Can anyone explain what normalizing means and provide a few example of a normalized value?
I think the confusion comes from the idea of normalizing "a value" as opposed to "a vector"; if you just think of a single number as a value, normalization doesn't make any sense. Normalization is only useful when applied to a vector.
A vector is a sequence of numbers; in 3D graphics it is usually a coordinate expressed as v = <x,y,z>.
Every vector has a magnitude or length, which can be found using Pythagora's theorem: |v| = sqrt(x^2 + y^2 + z^2) This is basically the length of a line from the origin <0,0,0> to the point expressed by the vector.
A vector is normal if its length is 1. That's it!
To normalize a vector means to change it so that it points in the same direction (think of that line from the origin) but its length is one.
The main reason we use normal vectors is to represent a direction; for example, if you are modeling a light source that is an infinite distance away, you can't give precise coordinates for it. But you can indicate where to find it from a particular point by using a normal vector.
It's a mathematical term and this link explains its meaning in quite simple terms:
Operations in 2D and 3D computer graphics are often performed using copies of vectors that have been normalized ie. converted to unit vectors... Normalizing a vector involves two steps:
calculate its length, then,
divide each of its (xy or xyz) components by its length...
It's something complicated to explain if you don't know too much about vectors or even vectorial algebra. (You can check this article about general concepts as vector, normal vector or even normalization procedure ) Check it
But the procedure or concept of "normalize" refers to the process of making something standard or “normal.”
In the case of vectors, let’s assume for the moment that a standard vector has a length of 1. To normalize a vector, therefore, is to take a vector of any length and, keeping it pointing in the same direction, change its length to 1, turning it into what is called a unit vector.
I have some discrete values and assumption, that these values lie on a Gaussian curve.
There should be an algorithm for max-calculation using only 3 discrete values.
Do you know any library or code in C/C++ implementing this calculation?
Thank you!
P.S.:
The original task is auto-focus implementation. I move a (microscope) camera and capture the pictures in different positions. The position having most different colors should have best focus.
EDIT
This was long time ago :-(
I'just wanted to remove this question, but left it respecting the good answer.
You have three points that are supposed to be on a Gaussian curve; this means that they lie on the function:
If you take the logarithm of this function, you get:
which is just a simple 2nd grade polynomial, i.e. a parabola with a vertical axis of simmetry:
with
So, if you know the three coefficients of the parabola, you can derive the parameters of the Gaussian curve; incidentally, the only parameter of the Gaussian function that is of some interest to you is b, since it tells you where the center of the distribution, i.e. where is its maximum. It's immediate to find out that
All that remains to do is to fit the parabola (with the "original" x and the logarithm of your values). Now, if you had more points, a polynomial fit would be involved, but, since you have just three points, the situation is really simple: there's one and only one parabola that goes through three points.
You now just have to write the equation of the parabola for each of your points and solve the system:
(with , where the zs are the actual values read at the corresponding x)
This can be solved by hand (with some time), with some CAS or... looking on StackOverflow :) ; the solution thus is:
So using these last equations (remember: the ys are the logarithm of your "real" values) and the other relations you can easily write a simple algebraic formula to get the parameter b of your Gaussian curve, i.e. its maximum.
(I may have done some mess in the calculations, double-check them before using the results, anyhow the procedure should be correct)
(thanks at http://www.codecogs.com/latex/eqneditor.php for the LaTeX equations)