Algorithms (millions of solid random intersections) - computational-geometry

I am looking for a numerical method to calculate the volume of the intersection of more than two cylinders in any angle (not just 90° (Steinmetz Solid)). There is an old Hubbell paper (1965) but it just work for two cylinders.
Evidently, I can make the calculation by hand, but I need a numerical method since I am making calculations for millions of random intersections.

Exact computation of the intersection volume looks like an endeavour. The graph of edges can have high complexity, and the edges are complicated skew curves.
I would try with a voxelization of space, one bit per voxel (2000³ voxels requiring 1GB of memory). Maybe an octree representation can help lower the storage requirement, with the number of cells required being closer to the area than to the volume.
Anyway, the filling of the cyclindres will take a quite significant amount of time.

Related

Finding random k points at least d apart in 3D confined space

For my simulation purposes, I want to generate a randomly distributed k number of spheres (having the same radii) in a confined 3D space (inside a rectangle) where k is in order of 1000. Those spheres should not impinge on one another.
So, I want to generate random k points in a 3D space at least d distance away from one another; considering the number of points and the frequency at which I need those points for simulation, I don't want to apply brute force; I'm looking for some efficient algorithms achieving this.
How about just starting with some regular tessellation of the space (i.e. some primitive 3d lattice) and putting a single point somewhere in each tile? You'd then only need to check a small number of neighboring tiles for proximity.
To get a more statistically uniform, i.e. less regular, set of points, you could:
perturb points in space
generate an overly dense lattice and reject some points
"warp" the space so that the lattice was more dense in certain areas
You could perturb the points sequentially, giving you a monte-carlo chain over their coordinates, and potentially saving work elsewhere. Presumably you could tailor this so that the equilibrium distribution was what you wanted.

How to estimate rough complexity of 3D models?

I'm having a project need categorize 3D models based on the complexity.
By "complexity", I mean for example, 3D model of furniture in modern style has low complexity, but 3D model of royal style furniture has very high complexity.
All 3D models are mesh type. I only need the very rough estimate, the reliability is not required too high, but should be correct most of times.
Please guide me which way, or the algorithm for this purpose (not based on vertices count).
It the best if we can process inside Meshlab, but any other source is fine too.
Thanks!
Let's consider a sphere: it looks simple, but it can be made of many vertices. I don't think that counting vertices gives a good estimation of complexity. The spheres' vertices are very little diverse.
Let's consider the old vs simple and modern furniture: the old one has potentially many different vertices but their organization is not "simple".
I propose to measure complexity to consider:
the number of different angles (and solid angles) between edges
the number of different edges' length (eg., connected vertices distances)
So far so good. But we got here by counting global complexity. What if with the same set of edges and vertices, we order them and build something that changes in a monotonic manner ? Yes, we need also to take into account local complexity: say the complexity in a limited chunk of space.
An algorithm is taking form:
divide the space into smaller spaces
count sets of different edges by angles and length
You can imagine take into account several scales by ranging the size of space divisions, and count sets every time, and in the end multiply or add the results.
I think you got something interesting. The thing is that this algorithm is rather close to some methods do estimate dimension of a fractal object.
Papers (google scholar) about "estimate fractal dimension"
3D models are composed of vertices, and vertices are connected together by edges to form faces. A rough measure of complexity from a computation standpoint would be to count the vertices or faces.
This approach falls down when trying to categorize the two chairs. It's entirely possible to have a simple chair with more vertices and faces than the regal chair.
To address that limitation I would merge adjacent faces with congruent normal vectors. If the faces share 1 edge and have congruent normal vectors then they can be said to be planar to each other. This would have the effect of simplifying the 3D model. A simple object should have a lower number of vertices / faces after this operation than a more complex model. At least in theory.
I'm sure there's a name for this algorithm, but I don't know it.

Optimally filling a 3D sphere with smaller spheres

I'm trying to optimally fill a 3D spherical volume with "particles" (represented by 3D XYZ vectors) that need to maintain a specific distance from each other, while attempting to minimize the amount of free space present in-between them.
There's one catch though- The particles themselves may fall on the boundary of the spherical volume- they just can't exist outside of it. Ideally, I'd like to maximize the number of particles that fall on this boundary (which makes this a kind of spherical packing problem, I suppose) and then fill the rest of the volume inwards.
Are there any kinds of algorithms out there that can solve this sort of thing? It doesn't need to be exact, but the key here is that the density of the final solution needs to be reasonably accurate (+/- ~5% of a "perfect" solution).
There is not a single formula which fills a sphere optimally with n spheres. On this wikipedia page you can see the optimal configurations for n <= 12. For the optimal configurations for n <= 500 you can view this site. As you can see on these sites different numbers of spheres have different optimal symmetry groups.
your constraints are a bit vague so hard to say for sure but I would try field approach for this. First see:
Computational complexity and shape nesting
Path generation for non-intersecting disc movement on a plane
How to implement a constraint solver for 2-D geometry?
and sub-links where you can find some examples of this approach.
Now the algo:
place N particles randomly inside sphere
N should be safely low so it is smaller then your solution particles count.
start field simulation
so use your solution rules to create attractive and repulsive forces and drive your particles via Newton D'Alembert physics. Do not forget to add friction (so movement will stop after time) and sphere volume boundary.
stop when your particles stop moving
so if max(|particles_velocity|)<threshold stop.
now check if all particles are correctly placed
not breaking any of your rules. If yes then remember this placement as solution and try again from #1 with N+1 particles. If not stop and use last correct solution.
To speed this up you can add more particles instead of using (N+1) similarly to binary search (add 32 particles until you can ... then just 16 ... ). Also you do not need to use random locations in #1 for the other runs. you can let the other particles start positions where they were placed in last run solution.
How to determine accuracy of the solution is entirely different matter. As you did not provide exact rules then we can only guess. I would try to estimate ideal particle density and compute the ideal particle count based on sphere volume. You can use this also for the initial guess of N and then compare with the final N.

What is the intuition behind the relationship between the dimensions of a model and the performance of k-nearest neighbors?

Regarding the properties of k-nearest neighbors, on page 38 of Elements of Statistical Learning, the authors write:
"...as the dimension p gets large, so does the metric size of the k-nearest neighborhood. So settling for nearest neighborhood as a surrogate for conditioning will fail us miserably."
Does this mean that, holding k constant, as we add features to a model, the distance between outcomes and thus the size of neighborhoods increases, so the model's variance increases?
The curse of dimensionality comes in various shapes. Especially for machine learning, there is a discussion here.
Generally, with increasing dimensionality, the relative difference in distances between points becomes increasingly small. For d=1000 dimensions, it is highly unlikely, that any point A in a random dataset is significantly closer to a given point B than any other point. In a way this can be explained by saying that with d=1000 it is very unlikely that a point A is closer to a point B in the vast majority of dimensions (at least unlikely to be closer than any other arbitrary point).
Another aspect is that the volumetric properties become unintuitive for increasing 'd'. For example, even when assuming a relatively moderate d=25 (if I remember correctly), the volume of a the unit-cube (length of edge = 1) is 1,000,000 bigger than the volume of the unit-sphere (sphere with diameter = 1). I mention this because your quote mentions 'metric size', but I'm not sure how this affects kNN.

Algorithm for partially filling a polygonal mesh

Overview:
I have a simple plastic sandbox represented by a 3D polygonal mesh. I need to be able to determine the water level after pouring a specific amount of water into the sandbox.
The water is distributed evenly from above when poured
No fluid simulation, the water is poured very slowly
It needs to be fast
Question:
What kind of techniques/algorithms could I use for this problem?
I'm not looking for a program or similar that can do this, just algorithms - I'll do the implementation.
Just an idea:
First you compute all saddle points. Tools like discrete morse theory or topological persistence might be useful here, but I know too little about them to be sure. Next you iterate over all saddle points, starting at the lowest, and compute the point in time after which water starts to cross that point. This is the time at which the shallower (in terms of volume versus surface area) of the two adjacent basins has reached a level that matches the height of that saddle point. From that point onward, water pouring onto that surface will flow over to the other basin and contribute to its water level instead, until the two basins have reached an equal level. After that, they will be treated as one single basin. Along the way you might have to correct the times when other saddle points will be reached, as the area associated with basins changes. You iterate in order of increasing time, not increasing height (e.g. using a heap with decrease-key operation). Once the final pair of basins have equal height, you are done; afterwards there is only a single basin left.
On the whole, this gives you a sequence of “interesting” times, where things change fundamentally. In between these, the problem will be much more local, as you only have to consider the shape of a single basin to compute its water level. In this local problem, you know the volume of water contained in that basin, so you can e.g. use bisection to find a suitable level for that. The adjacent “interesting” times might provide useful end points for your bisection.
To compute the volume of a triangulated polytope, you can use a 3D version of the shoelace formula: for every triangle, you take its three vertices and compute their determinant. Sum them up and divide by 6, and you have the volume of the enclosed space. Make sure that you orientate all your triangles consistently, i.e. either all as seen from the inside or all as seen from the outside. The choice decides the overall sign, try it out to see which one is which.
Note that your question might need refinement: when the level in a basin reaches two saddle points at exactly the same height, where does the water flow? Without fluid simulation this is not well defined, I guess. You could argue that it should be distributed equally among all adjacent basins. You could argue that such situations are unlikely to occur in real data, and therefore choose one neighbour arbitrarily, implying that this saddle point has infinitesimally less height than the other ones. Or you could come up with a number of other solutions. If this case is of interest to you, then you might need to clarify what you expect there.
A simple solution comes to mind:
binary-search your way through different heights of water, computing the volume of water contained.
i.e.
Start with an upper-estimate for the water's height of the depth D of the sandbox.
Note that since sand is porous, the maximum volume will be with the box filled to the brim with water;
Any more water would just pout back out into the grass in our hypothetical back-yard.
Also note, that this means that you don't need to worry about saddle points, or multiple water levels in your solution;
Again, we're assuming regular porous sand here, not mountains made out of rock.
Compute the volume of water contained by height D.
If it is within your approximation threshold, quit.
Otherwise, adjust your estimate with a different height, and repeat.
Note that computing the volume of water above the surface of the sand for any given triangular piece of the sand is easy.
It's the volume of a triangular prizm plus the volume of the tetrahedron which is in contact with the sand:
Note that the volume of water below the sandline would be calculated similarly, but the volume would be less, since part of it would be occupied by the sand.
I suggest internet-searching for typical air-void contents of sand, or water-holding capacity.
Or whatever phrases would return a sane result.
Also note, that some triangles may have zero water above the sand, if the sand is above the water-line.
Once you have the volume of water both above and below the sand-line for a single triangle of your mesh, you just loop over all of the triangles to get the total volume for your entire sandbox, for the given height.
Note that this is a pretty dumb algorithm, but I suspect it will have decent performance compared to a fancy-schmancier algorithm which would try to do anything more clever.
Remember that this is just a handful of multiplications and summations for each triangle, and that blind loops with few if statements or other flow-control tend to execute quickly, since the processor can pipeline it well.
This method may be parallelized easily instead of looping over each triangle, if you have a highly-detailed mesh of a sandbox, and want to shove the calculations into multiple cores.
Or keep the loops, and shove different heights into each core.
Or something else; I leave parallelization and speeding up as an exercise for the reader.

Resources