Bezier curve, get consistent points on axis? - bezier

So I have a bezier curve >
Now, I would like to get a y point, value every says, 0.01 value on x-axis.
As far as I know, there is no method to "find Y given X" using bezier.
So I have to subdivide it into flat straight chunks and then get... "somehow" nearest chunk value as an approximation?
So my question is, how can I... "equally" subdivide the bezier curve so that chunk distance is more equal on... x-axis?
Right now the chunk distancing that I get is quite... "random" using https://en.wikipedia.org/wiki/B%C3%A9zier_curve as my current algo.
Regards
Dariusz

As far as I know, there is no method to "find Y given X" using bezier.
Then you probably need to look for "finding Y given X" a bit more =) https://pomax.github.io/bezierinfo/#yforx
As for the result you want, with regularly spaced intervals based on distance along the curve is the general problem of reparameterizing the curve for distance rather than time., and it's a hard problem for quadratic, and literally impossible problem for higher order Beziers.
So instead of trying to do that, what we typically do is just build a lookup table by sampling the curve, storing those "t maps to x/y and distance d along the curve", and then we use that combined with interpolation to get good-enough approximate coordinates (e.g. sub-sub-pixel accurate) rather than mathematically perfect coordinates. https://pomax.github.io/bezierinfo/#tracing

Related

Solidworks Feature Recognition on a fill pattern/linear pattern

I am currently creating a feature and patterning it across a flat plane to get the maximum number of features to fit on the plane. I do this frequently enough to warrant building some sort of marcro for this if possible. The issue that I run into is I still have to manually set the spacing between the parts. I want to be able to create a feature and have it determine "best" fit spacing given an area while avoiding overlaps. I have had very little luck finding any resources describing this. Any information or links to potentially helpful resources on this would be much appreciated!
Thank you.
Before, you start the linear pattern bit:
Select the face2 of that feature2, get the outer most loop2 of edges. You can test for that using loop2.IsOuter.
Now:
if the loop has one edge: that means it's a circle and the spacing must superior to the circle's radius
if the loop has more that one edge, that you need to calculate all the distances between the vertices and assume that the largest distance is the safest spacing.
NOTA: If one of the edges is a spline, then you need a different strategy:
You would need to convert the face into a sketch and finds the coordinates of that spline to calculate the highest distances.
Example: The distance between the edges is lower than the distance between summit of the splines. If the linear pattern has the a vertical direction, then spacing has to be superior to the distance between the summit.
When I say distance, I mean the distance projected on the linear pattern direction.

sampling 2-dimensional surface: how many sample points along X & Y axes?

I have a set of first 25 Zernike polynomials. Below are shown few in Cartesin co-ordinate system.
z2 = 2*x
z3 = 2*y
z4 = sqrt(3)*(2*x^2+2*y^2-1)
:
:
z24 = sqrt(14)*(15*(x^2+y^2)^2-20*(x^2+y^2)+6)*(x^2-y^2)
I am not using 1st since it is piston; so I have these 24 two-dim ANALYTICAL functions expressed in X-Y Cartesian co-ordinate system. All are defined over unit circle, as they are orthogonal over unit circle. The problem which I am describing here is relevant to other 2D surfaces also apart from Zernike Polynomials.
Suppose that origin (0,0) of the XY co-ordinate system and the centre of the unit circle are same.
Next, I take linear combination of these 24 polynomials to build a 2D wavefront shape. I use 24 random input coefficients in this combination.
w(x,y) = sum_over_i a_i*z_i (i=2,3,4,....24)
a_i = random coefficients
z_i = zernike polynomials
Upto this point, everything is analytical part which can be done on paper.
Now comes the discretization!
I know that when you want to re-construct a signal (1Dim/2Dim), your sampling frequency should be at least twice the maximum frequency present in the signal (Nyquist-Shanon principle).
Here signal is w(x,y) as mentioned above which is nothing but a simple 2Dim
function of x & y. I want to represent it on computer now. Obviously I can not take all infinite points from -1 to +1 along x axis and same for y axis.
I have to take finite no. of data points (which are called sample points or just samples) on this analytical 2Dim surface w(x,y)
I am measuring x & y in metres, and -1 <= x <= +1; -1 <= y <= +1.
e.g. If I divide my x-axis from -1 to 1, in 50 sample points then dx = 2/50= 0.04 metre. Same for y axis. Now my sampling frequency is 1/dx i.e. 25 samples per metre. Same for y axis.
But I took 50 samples arbitrarily; I could have taken 10 samples or 1000 samples. That is the crux of the matter here: how many samples points?How will I determine this number?
There is one theorem (Nyquist-Shanon theorem) mentioned above which says that if I want to re-construct w(x,y) faithfully, I must sample it on both axes so that my sampling frequency (i.e. no. of samples per metre) is at least twice the maximum frequency present in the w(x,y). This is nothing but finding power spectrum of w(x,y). Idea is that any function in space domain can be represented in spatial-frequency domain also, which is nothing but taking Fourier transform of the function! This tells us how many (spatial) frequencies are present in your function w(x,y) and what is the maximum frequency out of these many frequencies.
Now my question is first how to find out this maximum sampling frequency in my case. I can not use MATLAB fft2() or any other tool since it means already I have samples taken across the wavefront!! Obviously remaining option is find it analytically ! But that is time consuming and difficult since I have 24 polynomials & I will have to use then continuous Fourier transform i.e. I will have to go for pen and paper.
Any help will be appreciated.
Thanks
Key Assumptions
You want to use the "Nyquist-Shanon" theorem to determine sampling frequency
Obviously remaining option is find it analytically ! But that is time
consuming and difficult since I have 21 polynomials & I have to use
continuous Fourier transform i.e. done by analytically.
Given the assumption I have made (and noting that consideration of other mathematical techniques is out of scope for StackOverflow), you have no option but to calculate the continuous Fourier Transform.
However, I believe you haven't considered all the options for calculating the transform other than a laborious paper exercise e.g.
Numerical approximation of the continuous F.T. using code
Symbolic Integration e.g. Wolfram Alpha
Surely a numerical approximation of the Fourier Transform will be adequate for your solution?
I am assuming this is for coursework or research rather, so all you really care about as a physicist is a solution that is the quickest solution that is accurate within the scope of your problem.
So to conclude, IMHO, don't waste time searching for a more mathematically elegant solution or trick and just solve the problem with one of the above methods

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.

Calculating distance in m in xyz between GPS coordinates that are close together

I have a set of GPS Coordinates and I want to find the speed required for a UAV to travel between them. Doing this by calculating distance in x y z and then dividing by time to travel - m/s.
I know the great circle distance but I assume this will be incorrect since they are all relatively close together(within 10m)?
Is there an accurate way to do this?
For small distances you can use the haversine formula without a relevant loss of accuracy in comparison to Vincenty's f.e. Plus, it's designed to be accurate for very small distances. This can be read up here if you are interested.
You can do this by converting lat/long/alt into XYZ format for both points. Then, figure out the rotation angles to move one of those points (usually, the oldest point) so that it would be at lat=0 long=0 alt=0. Rotate the second position report (the newest point) by the same rotation angles. If you do it all correctly, you will find X equals the east offset, Y equals the north offset, and Z equals the up offset. You can use Pythagorean theorm with X and Y (north and east) offsets to determine the horizontal distance traveled. Normally, you just ignore the altitude differences and work with horizontal data only.
All of this assumes you are using accurate formulas to convert lat/lon/alt into XYZ. It also assumes you have enough precision in the lat/lon/alt values to be accurate. Approximations are not good if you want good results. Normally, you need about 6 decimal digits of precision in lat/lon values to compute positions down to the meter level of accuracy.
Keep in mind that this method doesn't work very well if you haven't moved far (greater than about 10 or 20 meters, more is better). There is enough noise in the GPS position reports that you are going to get jumpy velocity values that you will need to further filter to get good accuracy. The math approach isn't the problem here, it's the inherent noise in the GPS position reports. When you have good reports, you will get good velocity.
A GPS receiver doesn't normally use this approach to know velocity. It looks at the way doppler values change for each satellite and factor in current position to know what the velocity is. This works reasonably well when the vehicle is moving. It is a much faster way to detect changes in velocity (for instance, to release a position clamp). The normal user doesn't have access to the internal doppler values and the math gets very complicated, so it's not something you can do.

Fitting curves to a set of points

Basically, I have a set of up to 100 co-ordinates, along with the desired tangents to the curve at the first and last point.
I have looked into various methods of curve-fitting, by which I mean an algorithm with takes the inputted data points and tangents, and outputs the equation of the cure, such as the gaussian method and interpolation, but I really struggled understanding them.
I am not asking for code (If you choose to give it, thats acceptable though :) ), I am simply looking for help into this algorithm. It will eventually be converted to Objective-C for an iPhone app, if that changes anything..
EDIT:
I know the order of all of the points. They are not too close together, so passing through all points is necessary - aka interpolation (unless anyone can suggest something else). And as far as I know, an algebraic curve is what I'm looking for. This is all being done on a 2D plane by the way
I'd recommend to consider cubic splines. There is some explanation and code to calculate them in plain C in Numerical Recipes book (chapter 3.3)
Most interpolation methods originally work with functions: given a set of x and y values, they compute a function which computes a y value for every x value, meeting the specified constraints. As a function can only ever compute a single y value for every x value, such an curve cannot loop back on itself.
To turn this into a real 2D setup, you want two functions which compute x resp. y values based on some parameter that is conventionally called t. So the first step is computing t values for your input data. You can usually get a good approximation by summing over euclidean distances: think about a polyline connecting all your points with straight segments. Then the parameter would be the distance along this line for every input pair.
So now you have two interpolation problem: one to compute x from t and the other y from t. You can formulate this as a spline interpolation, e.g. using cubic splines. That gives you a large system of linear equations which you can solve iteratively up to the desired precision.
The result of a spline interpolation will be a piecewise description of a suitable curve. If you wanted a single equation, then a lagrange interpolation would fit that bill, but the result might have odd twists and turns for many sets of input data.