6

I have a point cloud as X,Y,Z-coordinates which form a parallelepiped (with most data points inside the solid) that is rotated in space by some unknown amount and would like to find the 8 corners of it.

Basically, the answer could just be (using data.csv)

CFF[v_] := (v/{255, -255, 512})[[{3, 1, 2}]];
pts = CFF /@ Import["data.csv"];

H = ConvexHullMesh@pts
corners = MeshCoordinates@H

However, the mesh found by ConvexHullMesh looks like this:

Convex Hull

As you can see, there are a number of extra mesh points that are not inside but exactly on the 6 faces, so they get treated as belonging the convex hull.

How can I simplify the mesh, ie. remove coplanar points?

Thank you for any suggestions.

I have tried TriangulateMesh, but get a very unhelpful "TriangulateMesh failed to triangulate the mesh." DiscretizeRegion crashes the kernel in 11 and fails with "DiscretizeRegion was unable to discretize the region" in 10.

Martok
  • 63
  • 4
  • TriangulateMesh[%, MaxCellMeasure -> \[Infinity]]? – Feyre Jan 19 '17 at 14:34
  • @Feyre: tried that, "TriangulateMesh failed to triangulate the mesh." Also, DiscretizeRegion crashes the kernel. Added to question, sorry about that. – Martok Jan 19 '17 at 14:43
  • 1
    Helping you would be easier if you could post the "point cloud as X,Y,Z-coordinates which form a parallelepiped", here or in Pastebin if it's too long. – J. M.'s missing motivation Jan 19 '17 at 14:52
  • I have added a slightly decimated dataset that has the same issues. The reshaping is neccessary for the full processing, leaving it in because the type of the numbers might matter. – Martok Jan 19 '17 at 15:11
  • 1
    Region\Mesh`MergeCells` may be of use per this answer – Sterling Feb 04 '21 at 08:55
  • @Sterling seems like MergeCells should be the solution. But: "BoundaryMeshRegion::dgcell: The cell Polygon[{52,55,30,55}] is degenerate." Looks like the same issue the other functions have, ConvexHullMesh constructs something broken (but at least finally a proper error message, yay!). If someone could get this into a working answer with some details, I'll accept it, but it all seems very fragile to me... – Martok Feb 05 '21 at 17:48
  • @Martok, that's unfortunate. qhull via [qh-math] would probably work. A related question. As for that error, it makes sense that going from point 52-->55-->30 and then back to 55 would be an improper polygon (the last number should be 52, if I'm not mistaken). I tried using DetriangulateMesh from the linked question, but then got the error: "The number of vertices 2 given in Polygon[{36,60}] is incorrect for \ that cell type." All in all, pretty weird.. – Sterling Feb 05 '21 at 20:47

1 Answers1

4

We can find all the corners thusly:

i = Flatten@{Position[a = pts[[All, #]], Min@a] & /@ Range[3], 
    Position[a = pts[[All, #]], Max@a] & /@ Range[3]};
    corners = pts[[#]] & /@ i

{{0, 0, 0}, {359/512, -(256/255), -(89/255)}, {15/ 128, -(43/255), -(262/255)}, {1, 0, 0}, {153/512, 256/255, 89/ 255}, {113/128, 43/255, 263/255}}

Show[H, ListPointPlot3D[corners, PlotStyle -> {Red, PointSize[0.1]}]]

enter image description here

We can finish the set with:

corners = Join[corners, {corners[[3]] + corners[[5]], 
  corners[[3]] + corners[[6]], corners[[2]] - corners[[3]]}]

{{0, 0, 0}, {359/512, -(256/255), -(89/255)}, {15/ 128, -(43/255), -(262/255)}, {1, 0, 0}, {153/512, 256/255, 89/ 255}, {113/128, 43/255, 263/255}, {213/512, 71/85, -(173/255)}, {1, 0, 1/255}, {299/512, -(71/85), 173/255}}

ConvexHullMesh@corners

enter image description here

Feyre
  • 8,597
  • 2
  • 27
  • 46
  • That does indeed solve this particular application, but I do wonder if there isn't a way to do this using the geometric functions... – Martok Jan 19 '17 at 19:25
  • @Martok Like you said TriangulateMesh[] fails, that would be the go-to build in function to do this. – Feyre Jan 19 '17 at 19:43