I would like to know how to fit a bunch of (x,y) points in an ellipse shape. I've got two vectors, both the same size [1001,1], but I don't know how to fit an ellipse. Every time I tried the least squares it ends in some different approximation. I was using trigonometric polynomials by the way.
Here is an image of the graphic plot.
I will appreciate any help :)
Image plot: https://i.stack.imgur.com/P4vnt.png
Related
Given two points and a control point, one can easily draw a bezier path between the two points. What I would like to do use a bezier curve to draw a path that with changing width, by a assigning a "weight" to a the points of the curve which will determine its width. For example, if I give weight=0 to the first point of the curve and weight = 1 to the second point of the curve then something like the following path should be generated (the curve in the picture is cubic, but I am working with quadratic bezier curves):
In order to do this I would need to find the control points of the "edge" curves that determine the shape and then fill the shape that is found between the two new curves. However, I am quite unsure on how this can be done. One thing I thought about was to determine the starting and ending points of the new curves by simple drawing perpendicular segments to the line connecting the original control point and the original end points, but this still doesn't solve the problem of finding the new control points for the new curves.
I would use cubics instead of quadratics.
Yes you offset the control points perpendicularly by your weight but not the control points of BEZIER but control points of interpolation cubic (or catmull-rom) and then just convert that into Bezier control points. See related QAs:
How can i produce multi point linear interpolation?
How to create bezier curves for an arc with different start and end tangent slopes
draw outline for some connected lines
However much easier would be to directly render curve using Shaders and (perpendicular) distance. See:
Draw Quadratic Curve on GPU
That way you would not need to offset anything just interpolate the width of your curve ...
Maybe this could help, also there is an example on variable offseting
https://microbians.com/mathcode
Let's say I have a fitted curve in gnuplot (or simply sin(x) function) and file with data - points nearby the function. How to compute the distance of points from the curve and write them to the file with data in gnuplot? Is it possible to implement easily sum of squares in gnuplot? Thank you very much
Your question seems to mix two different concepts. If the curve was fitted to the points then the component term in the sum-of-squares uses the difference in y values. I.e. for a point [xi, yi] the term is (func(xi) - yi)**2.
But this is not the same thing as "distance of the point from the curve", since the nearest point on the curve may be at some different x value. The answer to that question in general requires calculus and is not something that gnuplot is designed to help you with, although if you work out the relevant equation you could use gnuplot's "fit" to find the minimum by approximation rather than by solving the differential equation analytically.
To plot the residuals after fitting
Assume data points [xi, yi] in columns 1 and 2 of file "data".
Assume fit(x) is the function you got from fitting. Then you can plot the residual for each point:
plot 'data' using 1:( (fit($1)-$2)**2 ) with linespoints
I'm trying to infer an object's direction of movement using dense optical flow in OpenCV. I'm using calcOpticalFlowFarneback() to get flow coordinates and cartToPolar() to acquire vector angles which would indicate direction.
To interpret the results I need to know the reference point for measuring the angle. I have found this blog post indicating that the range of angles is 360°. That tells me that the angle measurement would go along the lines of the unit circle. I couldn't make out much more than that.
The documentation for cartToPolar() doesn't cover this and my attempts at testing it have failed.
It seems that the angle produced by cartToPolar() is in reference to the unit circle rotated clockwise by 90° centered on the image coordinate starting point in the top left corner. It would look like this.
I came to this conclusion by using the dense optical flow example provided by OpenCV. I replaced the line hsv[...,0] = ang*180/np.pi/2 with hsv[...,0] = ang*180/np.pi to get correct angle conversion from radians. Then I tested a video with people moving from top right to bottom left and vice versa. I sampled the dominant color with GIMP and got RGB values which I converted to HSV values. Hue value corresponds to the angle in degrees.
People moving from top right to bottom left produced an angle of about 300° and people moving the other way round produced an angle of about 120°. This hinted at the way the unit circle is positioned.
Looking at the code, fastAtan32f is used to compute the angles. and that seems to be a atan2 implementation.
Bezier curve is a parametric curve, meaning that there is a paramater t at which one can evaluate the polynomials in order to find out the positions of points laying on the curve.
Polynomials for some common cases can be found at en.wikipedia.org/wiki/B%C3%A9zier_curve#Specific_cases
To draw a Bezier curve on screen, one could evaluate the polynomials from 0 to 1 at ever increasing t by tiny little steps. However, that would very wasteful because, in general, the parameter "space" does not correspond to screen "space", i.e. several little steps may fall onto just one pixel.
My question is: how to find the smallest step which increases Cartesian distance from previous point at least by 1 pixel?
To put it in other way: I would like to draw a Bezier curve on screen. How to choose the (uniform) step by which t should grow so that I never draw at one pixel more the once? I don't mind the "holes" when the t grows too quickly, I just don't want to redraw already drawn pixels.
Edit
By "how to find" I mean O(1). Yes, I could use De Casteljau's algorithm but I was hoping there is a way to "guess" the optimal t step quickly.
The comment above (jozxyqk) gives you a hint. I would give it a try with a recursive binary division of the spline drawing.
Lets say you start with a coarse resolution of the parameter space (delta_t = 0.1), that gives you 11 points on the spline curve s , s(t=0), s(t=0.1), ..., s(t=0.9), s(t=1).
Calculate the distance between s(t_i) and s(t_i+1). If it is >1 than make a binary subdivision between those two points. And so on...
But honestly, I guess it is faster to calculate all points a a higher resolution without any recursive loops or subdivisions. Especially if you are using multithread programming.
Looking at Convert a quadratic bezier to a cubic?, I can finally understand why programming teachers always told me that math was so important. Sadly, I didn't listen.
Can anyone provide a more concrete - e.g., computer-language-y - formula for converting a quadratic curve to a cubic? Understanding that there's some rounding errors possible, which is fine.
Given a quad curve represented by variables:
StartX, StartY
ControlX, ControlY
EndX, EndY
And desiring StartX, StartY and EndX, EndY to remain the same, but to now have Control1X, Control1Y and Control2X, Control2Y of a cubic curve.
Is it...
Control1X = StartX + (.66 * (ControlX - StartX))
Control2X = EndX + (.66 * (ControlX - EndX))
With the same essential functions used to calculate Control1Y and Control2Y?
Your code is right except that you should use 2.0/3.0 instead of 0.66.
You avoid most rounding errors by using
Control1 = (Start + 2 * Control) / 3
Control2 = (End + 2 * Control) / 3
Note that line segments are also convertible to cubic Bezier curves using:
Control1 = Start
Control2 = End
This can be handy when converting a complex path mixing various types of curves (linear, quadratic, cubic).
There's also a basic transform for converting elliptic arcs to cubic (with some minor unnoticeable errors): you just have to split at least the arc on elliptic quadrans (cutting the ellipse first on the two orthogonal axis of symetries, or on arbitrary orthogonal axis passing through the center if the ellipse is a circle, then representing each arc; when the ellipse is a circle, the two focal points are confused on the same point, the center of the circle, so you can use any direction for one of the orthogonal axis).
Many SVG renderers do that by adding an additional split on octants (so that you get also precise position not only for points where the two main axis are passing through, but also for two diagonal axis which are bissecting (when the ellipse is a circle) each quadrant (when the ellipse is not a circle, assimilate it as a circle flattened with a linear transform along the small axis only, you do the same computation), because octants are also quite precisely positioned:
cos(pi/4) = sin(pi/4) = sqrt(2)/2 ≈ 0.71, and because this additional splitting will allow precise rendering of tangents on points crossing the diagonals at 45 degrees of the circle.
A full ellipse is then converted to 8 cubic arcs (i.e. 8 points on ellipse and 16 control points): you'll almost not notice the difference between elliptical arcs and these generated cubic arcs
You can create an algorithm that uses the same "flattening error" computed when splitting a Bezier to a list of linear segments, which are then drawn using the classic fast Bresenham algo for line segments; a "flattenning" algorithm just has to measure the relative deviation of the sum of lengths of the two straight segments joining the two focal points of the ellipse to any point of the generated cubic arcs, as this sum is constant on any true ellipse: if you make this measurement on the generated control points for the cubic arcs, the difference should be below a given percentage of the expected sum, or within an absolute distance precision, and can be used to create better approximation of control points with a simple linear formula so that these added points will be on the real ellipse.
Such transform of arbitrary paths is useful when you want to derive other curves from the path, notably the curves of "buffers" at a given distance, notably when these paths must be converted to "strokes" with a defined "stroke width": you need to compute two "inner" and "outer" curves and then concentrate on how to converting the miters/buts/squares/rounded corners, and then to cut long miters at a convenient distance (matching the "miter limit" factor times the "stroke width").
More advanced renderers will also use miters represented by tangent circles when there's a corner between two arcs instead of two segments (this is useful for drawing cute geographic maps)...
Converting an arbitrary path mixing segments, elliptic and bezier arcs to only cubic arcs is a necessary step to compute precise images without excessive defects visible when zooming in. This is then necessary when your "stroke" buffers have to take some effects (such as computing dashes), and then enhancing the result with semi-transparent pixels or subpixels to smooth the rendered strokes (smoothing is easy to computez only when everything has been flattened to line segments, and alsos may be simpler to develop if it only has to manage paths containing only cubic beziers: it can easily be parallelized if needed and accelerated by hardware). Bezier arcs are always interesting because drawing them is fast and requires only basic arithmetics, and the time needed to draw them is proportional to the length of the curve with every point drawn with the same accuracy level.
In summary, all curves are representable by cubic Bezier arcs with a maximum measurable deviation allowed (you can set this maximum deviation to one half pixel, or one subpixel if you first scale up the measurement grid for half-toning or subpixel shading, and then represent accurately every curve with a reasonnaly fast rendering, and get accurate rendering at any zoom level with curves smoothed everywhere, including with half-toning or transparency levels when finally drawing the linear strokes with the classic Bresenham algorithm using fast integer-only arithmetics). These rendered curve will all have the correct tangeants everywhere, without any unexpected angles visible on approximation points, and the remaining control points in the approximation will make also a good smooth rendering of the curvature everywhere (i.e. radius of the tangeant circle), so you can use this approximation as well to derive other measurements such as acceleration, inertial forces, or magnetic effects of paths of charged particles).
If you ever need higher precision, use Bezier arcs with degree 4 (i.e. with 3 control points between points on curve) to get smoothed derivation at a supplementary degree (e.g. gradients of forces), or just split the cubic arcs with additional steps further, until the derivation is smooth enough (but using degree-4 Bezier arcs requires much less points curves and less control points for the same accuracy tolerances, than when using cubic Bezier only).