I want to determine a polygon's visual centre point in 3D space. Doing some initial research, I've come across this article by Vladimir Agafonkin describing one potential algorithm. However, the example implementations rely on other libraries and are tailored specifically for 2D space.
While rudimentary approaches (average, centroid, bounding box centre, etc.) work for simpler shapes such as regular convex polygons, it certainly gets hairier with irregular or concave polygons.
To help illustrate what I'm after, take these 2 example polygons:
The point that I'm interested in would be the red dot (as a Vector3 [x, y, z]).
Is there a way to achieve this in 3D space using vanilla Python (no third party modules)? Or another algorithm one of you have come across in your travels that may apply to this situation — or at the very least point me in the right direction?
Related
My general goal is going from a noisy point cloud describing a surface, to a regular surface mesh, in Python. I have found a few solution to this problem, none of which apply to my case well enough. The best ones I found:
B-spline -> sample it -> get new points. This calculates the z values of a function based on a regular set of x,y coordinates, which won't work well for near-vertical surfaces, of which I have a lot.
Rolling ball / convex hull algorithms. My data is noisy along the normal to the surface, so I would get a surface that's "inflated". I would need first to denoise it, which itself requires the calculation of a spline, or something similar.
I feel like there must be an "easy" way to do this, but I just don't know what to look for. Can someone point me in the right direction?
My best guess is that there should be a way to sample a spline surface "regularly" relatively to itself, but I can't figure out how.
The problem which you describe is named surface reconstruction. There is many algorithms and software (standalone program or libraries) able to reconstruct one surface from a set of sample points. There is important differences depending if you have only the XYZ coordinates of the points, or you have more information as the color or the normal to the surface.
Naming some examples, you can use:
Screened Poisson, by Kazhdan and Bolitho. Which is implemented in meshlab, and many other python libraries. Probably your best option.
PowerCRUST, by Nina Amenta, Sunghee Choi and Ravi Kolluri.
Ball Pivoting, by Bernardini, Mittleman, et al. Quite simple and easy to implement by yourself.
I have a sequence of points which are distributed in 2D space. They represent a shape but they are not ordered. So, I can plot them as points to give an idea of the shape, but if I plot the line connecting them, I miss the shape because the order of points is not the right order of connection.
I'm wondering, how can I put them in the right order such that, if I connect them one by one in sequence, I get a spline showing the shape they represent? I found and tried the convex hull in Matlab but with no results. The shape could be complex, for example a star and with convex hull I get a shape that is too much simplified (many points are not taken into account).
Thanks for help!
EDIT
Could be everything the image. I've randomly created one to show you a possible case, with some parts that are coming into the shape, and also points can have different distances.
I've tried with convex hull function in Matlab, that's what I get. Every time the contour have a "sharp corner", I miss it and the final shape is not what I'm looking for. Also, Matlab function has no parameter to set to change convex hull result (at least I can't see anything in the help).
hull = convhull(coords(:,1),coords(:,2));
plot(coords(hull,1),coords(hull,2),'.r');
You need to somehow order your points, so they can be in a sequence; in the case of your drawing example, the points can likely be ordered using the minimal distance, to the next -not yet used- point, starting at one end (you'll probably have to provide the end).
Then you can draw a spline, maybe using Chaikin's algorithm for curves that will locally approximate a bezier curve.
You need to start working on this, and post another question with your code, if you are having difficulties.
Alpha shapes may perform better than convexhulls for this problem. Alpha shapes will touch all the points in the exterior of a point cloud, even can carve out holes.
But for complicated shape reconstruction, I would recommend you to try a beta-skeleton bsed approach discussed in https://people.eecs.berkeley.edu/~jrs/meshpapers/AmentaBernEppstein.pdf
See more details on β-Skeleton at https://en.wikipedia.org/wiki/Beta_skeleton
Quote from the linked article:
The circle-based β-skeleton may be used in image analysis to reconstruct the shape of a two-dimensional object, given a set of sample points on the boundary of the object (a computational form of the connect the dots puzzle where the sequence in which the dots are to be connected must be deduced by an algorithm rather than being given as part of the puzzle).
it is possible to prove that the choice β = 1.7 will correctly reconstruct the entire boundary of any smooth surface, and not generate any edges that do not belong to the boundary, as long as the samples are generated sufficiently densely relative to the local curvature of the surface
Cheers
I get a pointcloud from my lidar which is basically an numpy array of points in 2D cartesian coordinates. Is there any efficient way to detect corners formed by such 2D points?
What I tried until now was to detect clusters, then apply RANSAC on each cluster to detect two lines and then estimate the intersection point of those two lines. This method works well when I know how many clusters I have (in this case I put 3 boxes in front of my robot) and when the surrounding of the robot is free and no other objects are detected.
What I would like to do is run a general corner detection, then take the points surrounding each corner and check if lines are orthogonal. If it is the case then I can consider this corner as feature. This would make my algorithm more flexible when it comes to the surrounding environment.
Here is a visualization of the data I get:
There are many many ways to do this. First thing I'd try in your case would be to chain with a reasonable distance threshold for discontinuities, using the natural lidar scan ordering of the points. Then it become a problem of either estimating local curature or, as you have done, grow and merge linear segments.
I'd like to make a convex hull of a set of 2D points (in python). I've found several examples which have helped, but I have an extra feature I'd like that I haven't been able to implement. What I want to do is create the convex hull but allow it to pick up interior points if they are sufficiently "close" to the boundary. See the picture below -> if theta < x degrees, then that interior point gets added to the hull.
Obvious this can make things a bit more complex, as I've found out from my thoughts and tests. For example, if an interior point gets added, then it could potentially allow another further interior point to be added.
Speed is not really a concern here as the number of points I'll be working with will be relatively small. I'd rather have a more robust algorithm then a quick one.
I'm wondering if anyone knows of any such example or could point me in the right direction of where to start. Thanks.
Concave hull might be what you're looking for, though it doesn't use an angle as far as I know. The algorithm that the LOCAL project uses seems to use k nearest neighbours.
You could first compute the convex hull, and then ruin round the edges of that seeing if any of the edges should be broken to include an interior point.
The notion you are looking for may be alpha-shape. Tuning alpha, you admit more or less points in your concave hull. Look at Edelsbrunner algorithm for alpha-shape finding.
I am currently trying to construct the area covered by a device over an operating period.
The first step in this process appears to be constructing a polygon of the covered area.
Since the pattern is not a standard shape, convex hulls overstate the covered area by jumping to the largest coverage area possible.
I have found a paper that appears to cover the concept of non-convex hull generation, but no discussions on how to implement this within a high level language.
http://www.geosensor.net/papers/duckham08.PR.pdf
Has anyone seen a straight forward algorithm for constructing a non-convex hull or concave hull or perhaps any python code to achieve the same result?
I have tried convex hulls mainly qhull, with a limited edge size with limited success.
Also I have noticed some licensed libraries that will not be able to be distributed, so unfortunately thats off the table.
Any better ideas or cookbooks?
You might try looking into Alpha Shapes. The CGAL library can compute them.
Edit: I see that the paper you linked references alpha shapes, and also has an algorithm listing. Is that not high level enough for you? Since you listed python as a tag, I'm sure there are Delaunay triangulation libraries in Python, which I think is the hardest part of implementing the algorithm; you just need to make sure you can modify the resulting triangulation output. The boundary query functions can probably be implemented with associative arrays.