Determining concavities of a non-convex polyhedron - mesh

Suppose to have a non-convex 3D polyhedron P, expressed as a mesh. What is the best algorithm for determining the set of all its concavities?
A first, maybe trivial, answer I thought could be to compute the convex hull C of the polyhedron P, and then to divide the insiemistic difference C - P into connected components. Could I be on the right direction? If yes, how do you compute the "difference" between meshes? Are there some CGAL functions I can use for "subtracting" meshes and getting the connected components.

Yes you can, you should look into the Nef_polyhedron_3 : https://doc.cgal.org/latest/Nef_3/classCGAL_1_1Nef__polyhedron__3.html
Basically you convert your mesh and its convex_hull mesh to nef. From there you get acces to Boolean Operations, including the Difference. So you can get what you want, and then convert it back to Polyhedron.

Related

In CGAL, can one convert a triangulation in more than three dimensions to a polytope?

If this question would be more appropriate on a related site, let me know, and I'd be happy to move it.
I have 165 vertices in ℤ11, all of which are at a distance of √8 from the origin and are extreme points on their corresponding convex hull. CGAL is able to calculate their d-dimensional triangulation in only 133 minutes on my laptop using just under a gigabyte of RAM.
Magma manages a similar 66 vertex case quite quickly, and, crucially for my application, it returns an actual polytope instead of a triangulation. Thus, I can view each d-dimensional face as a single object which can be bounded by an arbitrary number of vertices.
Additionally, although less essential to my application, I can also use Graph : TorPol -> GrphUnd to calculate all the topological information regarding how those faces are connected, and then AutomorphismGroup : Grph -> GrpPerm, ... to find the corresponding automorphism group of that cell structure.
Unfortunately, when applied to the original polytope, Magma's AutomorphismGroup : TorPol -> GrpMat only returns subgroups of GLd(ℤ), instead of the full automorphism group G, which is what I'm truly hoping to calculate. As a matrix group, G ∉ GL11(ℤ), but is instead ∈ GL11(𝔸), where 𝔸 represents the algebraic numbers. In general, I won't need the full algebraic closure of the rationals, ℚ̅, but just some field extension. However, I could make use of any non-trivially powerful representation of G.
With two days of calculation, Magma can manage the 165 vertex case, but is only able to provide information about the polytope's original 165 vertices, 10-facets, and volume. However, attempting to enumerate the d-faces, for any 2 ≤ d < 10, quickly consumes the 256 GB of RAM I have at my disposal.
CGAL's triangulation, on the other hand, only calculates collections of d-simplices, all of which have d + 1 vertices. It seems possible to derive the same facial information from such a triangulation, but I haven't thought of an easy way to code that up.
Am I missing something obvious in CGAL? Do you have any suggestions for alternative ways to calculate the polytope's face information, or to find the full automorphism group of my set of points?
You can use the package Combinatorial maps in CGAL, that is able to represent polytopes in nD. A combinatorial map describes all cells and all incidence and adjacency relations between the cells.
In this package, there is an undocumented method are_cc_isomorphic allowing to test if an isomorphism exist from two starting points. I think you can use this method from all possible pair of starting points to find all automorphisms.
Unfortunatly, there is no method to build a combinatorial map from a dD triangulation. Such method exists in 3D (cf. this file). It can be extended in dD.

Using libigl's uniformly_sample_two_manifold

I'm trying to use the function of libigl uniformly_sample_two_manifold, but it does not work as described and there is no documentation whatsoever to help me understand why.
I have a 3D mesh represented as Eigen::MatrixXd V with vertices and Eigen::MatrixXi F with faces. I'm attempting to use the function as follows:
igl::uniformly_sample_two_manifold(V, F, 20, 1.0, Out);
... giving the function my vertices, faces, and asking for 20 uniform samples in the Out structure. I set the "push factor" to 1 since I don´t think I have any use for it now.
I noticed that the function specifically askes for "positions of mesh in weight space", which I presumed means the vertex positions. If I use it like this, however, the function returns the expected amount of vertices which are clustered very close to each other and are by no means uniformly distributed across the mesh.
Does anyone happen to know how to correctly use this function? Or would anyone know what does this "weight space" mean?
Thanks!

Polyhedron Placement Optimization

I want to place one polyhedron(Object) into another (Container). Both the polyhedrons are convex and defined by a set of points and triangles. The container has a constant size. The object can be scaled and should be strictly inside the container. I want to compute the position and orientation for the object which makes it the biggest. Approximate and efficient solutions also help.
Any suggestions? Thanks a lot.
Suggestion for a quick & suboptimal solution, based on ellipsoids:
For both vertex sets, center around the gravity center and normalize the coordinates by computing the equivalent ellipsoid of inertia, giving you a more isotropic set.
For the outer set, find the shortest distance between the faces and the origin; for the inner set, find the farthest distance to a vertex. This gives you two spheres, one enclosed, one enclosing.
Now transform the enclosed sphere to the coordinates of the enclosing one, giving an ellipsoid: the longer axis of the ellipsoid tells you how much you can inflate it to fit in the sphere.
This approximation can be poor if the polyhedra are skewed.
You can slightly improve this solution by drawing rays from the center of the inner polyhedron through all vertices, and hitting the outer polyhedron, possibly giving you an extra growth factor.
Another suggestion, if running-time allows it:
For a fixed pose of the outer polyhedron, the pose of the inner polyhedron is defined by 3 translation and 3 rotation parameters (such as Euler angles) around an arbitrary center.
When these parameters are fixed, casting rays from the center through the inner vertices until you hit the outer polyhedron gives you the allowed scaling factor.
Now the problem is recast as the maximization of a function of 6 variables, with local maxima to be expected. This can be addressed by Hooke & Jeeves steps, the up-hill simplex method (Nelder-Mead) and/or simulated annealing.
I do not recommend to start from the solution in my other answer and stay close to it, as you could be trapped in a local maximum.

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.

Solving for optimal alignment of 3d polygonal mesh

I'm trying to implement a geometry templating engine. One of the parts is taking a prototypical polygonal mesh and aligning an instantiation with some points in the larger object.
So, the problem is this: given 3d point positions for some (perhaps all) of the verts in a polygonal mesh, find a scaled rotation that minimizes the difference between the transformed verts and the given point positions. I also have a centerpoint that can remain fixed, if that helps. The correspondence between the verts and the 3d locations is fixed.
I'm thinking this could be done by solving for the coefficients of a transformation matrix, but I'm a little unsure how to build the system to solve.
An example of this is a cube. The prototype would be the unit cube, centered at the origin, with vert indices:
4----5
|\ \
| 6----7
| | |
0 | 1 |
\| |
2----3
An example of the vert locations to fit:
v0: 1.243,2.163,-3.426
v1: 4.190,-0.408,-0.485
v2: -1.974,-1.525,-3.426
v3: 0.974,-4.096,-0.485
v5: 1.974,1.525,3.426
v7: -1.243,-2.163,3.426
So, given that prototype and those points, how do I find the single scale factor, and the rotation about x, y, and z that will minimize the distance between the verts and those positions? It would be best for the method to be generalizable to an arbitrary mesh, not just a cube.
Assuming you have all points and their correspondences, you can fine-tune your match by solving the least squares problem:
minimize Norm(T*V-M)
where T is the transformation matrix you are looking for, V are the vertices to fit, and M are the vertices of the prototype. Norm refers to the Frobenius norm. M and V are 3xN matrices where each column is a 3-vector of a vertex of the prototype and corresponding vertex in the fitting vertex set. T is a 3x3 transformation matrix. Then the transformation matrix that minimizes the mean squared error is inverse(V*transpose(V))*V*transpose(M). The resulting matrix will in general not be orthogonal (you wanted one which has no shear), so you can solve a matrix Procrustes problem to find the nearest orthogonal matrix with the SVD.
Now, if you don't know which given points will correspond to which prototype points, the problem you want to solve is called surface registration. This is an active field of research. See for example this paper, which also covers rigid registration, which is what you're after.
If you want to create a mesh on an arbitrary 3D geometry, this is not the way it's typically done.
You should look at octree mesh generation techniques. You'll have better success if you work with a true 3D primitive, which means tetrahedra instead of cubes.
If your geometry is a 3D body, all you'll have is a surface description to start with. Determining "optimal" interior points isn't meaningful, because you don't have any. You'll want them to be arranged in such a way that the tetrahedra inside aren't too distorted, but that's the best you'll be able to do.