Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to find a way of drawing the inside of a closed 2D curve. This curve is actually created using a bicubic Bezier curve, but that's not important I believe.
At the moment there should be no "holes" within the drawn shape. So it will just be totally filled in. It seems like constrained Delaunay triangulation would be the way to go? But there seems to be different ways of doing this. I am looking for a quick and simple solution (but will implement what's needed to make it working).
Programs such as Illustrator have that sort of feature (or SVG -- with the option fill).
I am looking for:
techniques to do that
point me to a paper/document where the algorithm is explained
is the source code of a SVG renderer available somewhere?
EDIT:
The application uses OpenGL. I draw the curves myself. Just need to find a way of filling them in.
the shape can either be concave or convex
Polygons can be filled using the Scanline method. The principle is easy: move an horizontal line and keep a list of the edges it meets. It is called the active list. Then join the intersections from left to right, in pairs. When the edges are sorted by increasing ordinate, the update of the active list from one scanline to the next can be done efficiently.
This works with concave/convex polygons and polygons with holes, and even crossed ones.
To fill a Bezier path, you can flatten it, i.e. turn it to a polygon of many sides.
A direct approach is also possible, based on the scanline idea: first decompose the Bezier curves in monotone sections, i.e. portions that meet on horizontal line only once. This can be done analytically for cubic Beziers by detecting the curve maxima and minima (the equation is quadratic).
Now you can treat the curvilinear polygon exactly as a polygon, knowing that you have one intersection per side. There is a slightly delicate point, computing the intersection. But this is eased by the fact that you know a good approximation of the Bezier arc (the line segment between the same endpoints), and you can update the intersection incrementally, from one scanline to the next.
On the picture, the original endpoints appear in blue. Splitting endoints have been added to obtain monotone sections (the other control points are omitted). The dotted lines shows the polygon that approximates the shape and has the same topology (same active list, same number of intersections with the scanlines).
If you must use polygon filling, there is no other option than flattening the curve to get straight sides.
Then use a polygon filling primitive.
If all you have is a triangle filling primitive, you can
triangulate the polygon by ear clipping, or decomposition in monotone polygons, or
use a simple sweepline method: if you draw an horizontal through every vertex, you will slice the polygon in triangles and trapezoids. A trapezoid can be cut in two triangles. For efficiency, use the active list method.
Related
In my program, I want to implement the following features:
Users draw a closed curve using mouse, and this curve is actually a set of point
Given a closed curve drawn by users, this program would create equilateral triangles inside this curve to get a 2d mesh.
Just like this image, the first one is the closed curve drawn by user. Then I want to create equilateral triangles inside this curve(the second one), and move those points which are not in these created triangles's vertex to get a 2d mesh(the third one).
I've looked up CGAL which has a lot of mesh generation algorithm, but I can't find a way to do what I need. So does anyone know how I could achieve my goal.
If your curve is closed then you can use the 2D meshing package. A simple example is here.
Here is an example I generated using CGAL embedded into the Ipe software.
Let's define a curve as set of 2D points which can be computed to arbitrary precision. For instance, this is a curve:
A set of N intersecting curves is given (N can be arbitrarily large), like in the following image:
How to find the perimeter of the connected area (a bounding box is given if necessary) which is delimited by the set of curves; or, given the example above, the red curve? Note that the perimeter can be concave and it has no obvious parametrization.
A starting point of the red curve can be given
I am interested in efficient ideas to build up a generic algorithm however...
I am coding in C++ and I can use any opensource library to help with this
I do not know if this problem has a name or if there is a ready-made solution, in case please let me know and I will edit the title and the tags.
Additional notes:
The solution is unique as in the region of interest there is only a single connected area which is free from any curve, but of course I can only compute a finite number of curves.
The curves are originally parametrized (and then affine transformations are applied), so I can add as many point as I want. I can compute distances, lengths and go along with them. Intersections are also feasible. Basically any geometric operation that can be built up from point coordinates is acceptable.
I have found that a similar problem is encountered when "cutting" gears eg. https://scialert.net/fulltext/?doi=jas.2014.362.367, but still I do not see how to solve it in a decently efficient way.
If the curves are given in order, you can find the pairwise intersections between successive curves. Depending on their nature, an analytical or numerical solution will do.
Then a first approximation of the envelope is the polyline through these points.
Another approximation can be obtained by drawing the common tangent to successive curves, and by intersecting those tangents pairwise. The common tangent problem is more difficult, anyway.
If the equations of the curves are known in terms of a single parameter, you can find the envelope curve by solving a differential equation, obtained by eliminating the parameter between the implicit equation of the curve and this equation differentiated wrt the parameter. You can integrate this equation numerically.
When I have got such problems (maths are not enough or are terribly tricky) I decompose each curve into segments.
Then, I search segment-segment intersections. For example, a segment in curve Ci with all of segments in curve Cj. Even you can replace a segment with its bounding box and do box-box intersection for quick discard, focusing in those boxes that have intersection.
This gives a rough aproximation of curve-curve intersections.
Apart from intersections you can search for max/min coordinates, aproximated also with segments or boxes.
Once you get a decent aproximation, you can refine it by reducing the length/size of segments and boxes and repeating the intersection (or max/min) checks.
You can have an approximate solution using the grids. First, find a bounding box for the curves. And then griding inside the bounding box. and then search over the cells to find the specified area. And finally using the number of cells over the perimeter approximate the value of the perimeter (as the size of the cells is known).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a set of 2D points and I want to find the potential largest empty circle. By that, I don't mean to code the Largest Empty Circle algorithm.
Here's an image trying to explain my words.
As you can see, there are points inside that circle, so what I want is an algorithm that given that set of 2D points, could compute that circle.
That set of points represents a wall of a sewer which contains a hole. The problem is that this hole may be corked, may contain some dirt at one or more sides of the circle. So, when you laser detect that part, you don't obtain a perfect circle, but kind of a semicircle. What I want to find is the original hole, the clean hole, when there is no dirt. When I say potential, I mean the original hole. In the image, the green circle is the original hole and the points inside that circle are some kind of dirt. The final purpose of this is to decide whether the hole is clean or dirty (Detecting how many points are inside that green circle and decide how dirty it is)
Another example of how it is supposed to be in real life:
Here you can see that the hole has dirt in the bottom part (could be any side of the hole), so when you laser detect it, you don't obtain the circle, but a bunch of points with the upper part of the circle as empty. What I want is from that set of points where you can only see the upper part of the circle empty, reconstruct the original hole, as it was when clean.
Plus, I attach two images of the point cloud, from two different perspectives, so you can know what I am working with.
I would find the bounding box of hole and then inspect the sides. find the one that is not linear but curved instead and set that as circle border. Then fit circle to that side only. For more info see:
fitting ellipses
Finding holes in 2d point sets
If you can scale the coordinates in order to draw the point into an image, here is a solution:
Draw the points into an image
Compute the distance map using all the points as a source point.
Then, each pixel will contain the distance to the closets point. So the pixel with the highest value will be the center of the largest circle, and the pixel value will be the circle radius.
Find the closest points to the circle center.
Find the circle passing by all theses points (Hough?). The solution might not be unique.
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.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I know I need to project the vertices of my polyhedra on a whole bunch of axes, i've read these axes are the normals to each of the faces of one polyhedra (or is it both?). I've also read i use the cross product of each edge of one collidable with each edge of the other collidable. So lets say i have 2 polyhedra each with 8 faces and 12 edges. Therefore there would be 8 + (12*12) = 152 axes to project and then subsequently test? Is that correct?
Also since i dont know whether my faces are CW or CCW, my normals could be pointing inside or outside, does this matter? For example lets say i project onto an axis that is a normal from one of the shapes facing inwards, as long as both polyhedra are projected using this same normal, will this effect the algorithm?
Thanks for any input!
The theorem says that you project the polyhedrons to a 2D plane and if you find an axis on which they don't overlap they don't collide. The problem is to find the right plane/axis in the least amount of attempts. So you use the polyhedron face's normals as separating axes for test as well as their cross product for test if they collide on the edges.
In your example if you have 2 polyhedrons each with 8 faces and 12 edges, you first test the 8 normals of each polyhedron as the separating axes. If each of them a separating axes you can assume that the polyhedrons don't collide. Then you can check the cross products of the normals as separating axes to eliminate the edge-on-edge non-colliding cases.
I hope this helped.
In short, the only planes you need to check are those that are defined by the faces of your objects; that is, the normal of the faces is the normal of the planes to check. The direction of the normal doesn't matter, since you're just projecting the vertices anyway.
Also note that this only works for convex meshes, and isn't necessarily the quickest way to do these kinds of checks. You might want to look into XenoCollide or GJK instead; those are becoming standard.