I have a list of points say
a, b, c and d
that I want to join like
a - b - c - d.
Right now I'm just taking two points at a time and drawing a line between them. But the result is sharp corners. So I thought of joining them with curves so that corners are smooth. I read about Bezier curves to draw curves but that requires additional control points to draw the curve. I also couldn't get how to join multiple points in a row using curves. Is there some way of doing that or something that can I can do or work on to make this possible?
I am using both opengl and SVG to output the result.
Catmull-Rom splines are perhaps the easiest way to join up points with curves without needing additional control points (well you need a couple of extra points at the beginning and end, but you can trivially make those up like e=d+(d-c)). This looks like a good primer: https://www.mvps.org/directx/articles/catmull/
I find it can be difficult to get aesthetically pleasing curves when the points are very unevenly spaced though.
Related
I have a bunch of (2D) polygons where I need to compute hatch (fill) lines for (distance between lines and angle is variable). Some of the polygons can be embedded in other ones forming some kind of "holes" which then should be excluded from being hatched.
My question: is there a package/library available in CGAL which supports such a calculation?
A plain OpenGL effect with textures or something like this would not do the trick in my case, I really need a bunch of vector lines as result of this operation because it not only has to be displayed at a screen.
Thanks!
For sure, you can achieve what you want using the Arrangement package. But there are many ways to do it.
Maybe the simplest would be to first crop your hatch lines to segments and then compute an arrangement of segments using the hatch lines and polygon segments.
Then you can filter edges you are not interested in. It might be a good idea to use arrangement with history to get back to the original curves.
Clipping each hatch line against the polygons (and their holes) and merging the results would result in the desired vector representation. CGAL has a package for such boolean operations on polygons: 2D Regularized Boolean Set-Operations (see Boolean Set-Operations on Linear Polygons in the documention).
There a is an ellipse on the picture,just as following.
I have got the points of the contour by using opencv. But you can see the pictrue,because the resolution is low, there is a straight line on the contour.How can i fit it into curve like the blue line?
One Of the method to solve your problem is to vectorize your shape (moving from simple intensity space to vectors space).
I am not aware of the state-of-art in this field. However, from school information, I can suggest this solution.
Bezier curves, you can try to model your shape using simple bezier curve.This is not a hard operation you can google for dozen of them. Then, you can resizing it as much as you want after that you may render it to simple image.
Be aware that you may also Splines instead of Bezier.
Another method would be more simple but less efficient. Since you mentioned OpenCV, you can apply the cv::fitEllipse on the points. Be aware that this will return a RotatedRect which contains the ellipse. You can infer your ellipse simply like this:
Center = Center of RotatedRect.
Longest Radius = The Line which pass from the center and intersect with the two small sides of the RotatedRect.
Smallest Radius = The Line which pass from the center and intersect with the two long sides of the RotatedRect.
After you got your Ellipse Parameters, You can resize it as you want then just repaint it in the size you want using cv::ellipse.
I know that this is a pseudo answer. However, I think every thing is easy to apply. If you faced any problem implementing it, just give me a comment.
I have various point clouds defining RT-STRUCTs called ROI from DICOM files. DICOM files are formed by tomographic scanners. Each ROI is formed by point cloud and it represents some 3D object.
The goal is to get 2D curve which is formed by plane, cutting ROI's cloud point. The problem is that I can't just use points which were intersected by plane. What I probably need is to intersect 3D concave hull with some plane and get resulting intersection contour.
Is there any libraries which have already implemented these operations? I've found PCL library and probably it should be able to solve my problem, but I can't figure out how to achieve it with PCL. In addition I can use Matlab as well - we use it through its runtime from C++.
Has anyone stumbled with this problem already?
P.S. As I've mentioned above, I need to use a solution from my C++ code - so it should be some library or matlab solution which I'll use through Matlab Runtime.
P.P.S. Accuracy in such kind of calculations is really important - it will be used in a medical software intended for work with brain tumors, so you can imagine consequences of an error (:
You first need to form a surface from the point set.
If it's possible to pick a 2d direction for the points (ie they form a convexhull in one view) you can use a simple 2D Delaunay triangluation in those 2 coordinates.
otherwise you need a full 3D surfacing function (marching cubes or Poisson)
Then once you have the triangles it's simple to calculate the contour line that a plane cuts them.
See links in Mesh generation from points with x, y and z coordinates
Perhaps you could just discard the points that are far from the plane and project the remaining ones onto the plane. You'll still need to reconstruct the curve in the plane but there are several good methods for that. See for instance http://www.cse.ohio-state.edu/~tamaldey/curverecon.htm and http://valis.cs.uiuc.edu/~sariel/research/CG/applets/Crust/Crust.html.
I have N points in 3-dimensional space. I need to join them using a line. However, if I do that using a simple line, it is not smooth and looks ugly.
My current approach is to use a Bezier curve, using the DeCasteljau algorithm for 4 points, and running that for each group of 4 points in my data set. However, the problem with this is that since I run it on say points 1-4, 5-8, 9-12, etc., separately, the line is not smooth between 4-5, 8-9, etc.
I also looked for other approaches; specifically I found this article about Catmull-Rom splines, which seem even better suited for my purpose, because the curve passes through all control points, unlike the Bezier curve. So I almost started implementing that, but then, I saw on that site that the formula works "assuming uniform spacing of control points". That is not the case for my problem.
So, my question is, what approach should I use -- Bezier, Catmull-Rom, or something completely different? If Bezier, then how to fix the non-smoothness between 4-5, 8-9, etc.? If Catmull-Rom, why won't the formula work if points are not evenly spaced, and what do I need instead?
EDIT: I am now pretty sure I want the Catmull-Rom spline, as it passes every control point which is an advantage for my application. Therefore, the main question I would like answered is why won't the formula on the link I provided work for non-uniformly spaced control points?
Thanks.
A couple of solutions:
Use a B-spline. This is a generalization of Bezier curves (a Bezier curve is a B-spline with no internal knot points.)
Use a cubic spline. Cubic splines are particularly easy to calculate. A cubic spline is continuous in the zero, first, and second derivatives across the control points. The third derivative, the cubic term, suffers a discontinuity at the control points, but it is very hard to see those discontinuities.
One key difference between a B-spline and a cubic spline is that the cubic spline will pass through all of the control points, while a B-spline does not. One way to think about it: Those internal control points are just suggestions for a B-spline but are mandatory for a cubic spline.
A meaningful line (although not the simplest to evaluate) can be found via Gaussian Processes. You set (or infer) the lengthscale over which you wish the line to vary (i.e. the smoothness of the line) and then the GP line is the most probable line through the data given the lengthscale. You can add noise to the model if you don't mind the line not passing through the data points.
Its a nice interpolation method because you can also obtain the standard deviation of your line. The line becomes more uncertain when you don't have much data in the vacinity.
You can read about them in chapter 45 of David MacKay's Information Theory, Inference, and Learning Algorithms - which you can download from the author's website here.
one solution is the following page in wikipedia: http://en.wikipedia.org/wiki/Bézier_curve, check the generalized approach for N control points.
I was wondering what would be the best and less complicated way of drawing a bezier curve in c++ with a set of points (roughly 100+ points) that are stored inside a vector
From my understanding:
-Bezier curves consist of 4 control points, the points in the middle dictate the direction/tangent of the curve
Would one possible method be to breakdown the points into different segments and from each segment determine the control points and tangents?
It is called a cubic spline and if you search you might find some C++ code for it. I used the free Fortran code from Numerical Recipes Online and ported it to C# with no problems.
Would one possible method be to
breakdown the points into different
segments and from each segment
determine the control points and
tangents?
Yes, basically one connects the line segments end-to-end such that the slope approaching the end of the line segment is equal on both sides of the connection point. This is called a cubic spline. You can find algorithms for this here.