Surface dilatation/erosion on a mesh - c++

I am performing plane detection on a 3D mesh. To fill small holes, I want to perform a dilatation/erosion step. For each planes I know the equation and the corresponding facets (represented by a set corresponding to the ids of the facets).
Currently, I have the following algorithm :
set<int> sFacetsDil;
for(set<int>::iterator it = Planes.sFacets.begin(); it != Plane.sFacets.end(); it++)
{
Facet f = facetMap.at(*it);
vector<Facet> vFacets = facetAround(f);
for(int i = 0; i < vFacets.size(); i++) {
if(isNotInPlane(vFacets[i]))
sFacetsDil.insert(vFacets[i].id);
}
}
Plane.sFacets.insert(sFacetsDil.begin(), sFacetsDil.end());
I do roughly the same thing for the erosion step. However this is quite ineffective: some facets are inside the plane and don't have to be visited for the dilatation steps. I understand I could compute the border of the plane, but I think in the end it would end at iterating over all the facets to find it... Moreover, there are some cases where I'd like to do multiple dilatation steps. So every time the border would have to be computed.
I have the standard halfedge structure for the mesh.
Does anyone know if there is a standard algorithm for this problem?

Related

Draw (2D) Polygon with given 3D-Vertices and Transformation with VTK

I have some 3d models and I want to display each face of the model seperately. For each face, I have a list of the vertices (as pcl::PointCloud), the Translation vector (as Eigen::Vector3f) and the Rotation Matrix (as Eigen::Quaternionf). The faces can have different shapes. It will be rectangular, round (n-verts polygon) and trapezial.
For the rectangular faces, I used vtkCubeSource so far and it works good. For the round faces, I could maybe use vtkCylinderSource. For trapezial faces, I didn't found a solution so far.
The best would be a class like vtkPolyLineSource, where I just need a list of vertices for any polygons. But as far as I see, vtkPolyLineSource would just draw the the line and don't fill the polynom with a color.
Is there a way to draw a polygon into 3d-space with vtk? Since it is possible to directly draw a 3d-model from a file, I think there should be a method for drawing a model (or just one face), but I couldn't find it so far. That's my first contact with VTK, so I think I just overlooked the right classes.
One reason why I don't just load a model-file is, that I need the faces in different colors and opacitys (defiend at runtime).
Use vtkPolygon
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
// ... fill in your points with n points
// Create the polygon
vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
polygon->GetPointIds()->SetNumberOfIds(n);
for (int j = 0; j < n; j++)
{
polygon->GetPointIds()->SetId(j, j);
}
// Add the polygon to a list of polygons
vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
polygons->InsertNextCell(polygon);
// Create a PolyData
vtkPolyData* polygonPolyData = vtkPolyData::New();
polygonPolyData->SetPoints(points);
polygonPolyData->SetPolys(polygons);
// create mapper and actor using this polydata - the usual stuff

Arrange particles in the shape of a rectangle

I have a particle simulation program I'm currently working on that generate random particle positions in a rectangular shape. This works for now but it's not the best solution, often particles overlap and there are small holes in the rectangle. How would I initialize the particles in the shape of a rectangle?
My current loop:
for(auto i=0; i<MAXPARTICLES; i++){
int particleIndex = FindUnusedParticle(); //grab the index to give a particle life
ParticlesContainer[particleIndex].life = 100.0f; //Long particle life
//generate random positions for particles in the shape of a box with random patterns
ParticlesContainer[particleIndex].pos = glm::vec3((rand()%50)/5.0,(rand()%50)/5.0,-50.0);
// Very bad way to generate a random color
ParticlesContainer[particleIndex].r = 255;
ParticlesContainer[particleIndex].g = 0;
ParticlesContainer[particleIndex].b = 0;
ParticlesContainer[particleIndex].a = 255;
ParticlesContainer[particleIndex].size = .2f;
}
It's a more complicated problem than just using uniform distribution over two dimensions separately. If your "evenliness" is the distance between two closest particles, then there are exactly two ways to achieve that: equilateral triangles and squares (well, three if you count hexagons). The only random thing there is the position of one seed and the "direction" in which that will go.
Refer to the image:
That will give you a very regular, grid-like look, though. You could try applying random, minuscule changes to particles distributed that way, and see how that would work.

Brute force collision detection for two objects too slow

I have a project to see if two objects (made of about 10,000 triangles each) collide using the brute force collision algorithm, rendered in OpenGL. The two objects are not moving. I will have to translate them to some positions and find e.g. 100 triangle collisions etc.
So far I have written a code that actually checks for line-plane intersection between these two models. If I got everything straight I need to check every edge of every triangle of the first model with the each plane of each triangle of the other model. This actually means 3 'for' loops that take hours to end. I suppose I must have something wrong or got the whole concept misunderstood.
for (int i=0; i<model1_faces.num; i++) {
for (int j=0; j<3; j++) {
x1[j] = model1_vertices[model1_faces[i].v[j]-1].x;
y1[j] = model1_vertices[model1_faces[i].v[j]-1].y;
z1[j] = model1_vertices[model1_faces[i].v[j]-1].z;
}
A.x = x1[0];
A.y = y1[0];
A.z = z1[0];
B.x = x1[1];
B.y = y1[1];
B.z = z1[1];
C.x = x1[2];
C.y = y1[2];
C.z = z1[2];
TriangleNormal = findNormalVector((B-A)*(C-A));
RayDirection = B-A;
for (int j=0; j<model2_faces.num; j++) {
PointOnPlane = model2_vertices[model2_faces[j].v[0]-1]; // Any point of the triangle
system("PAUSE");
float D1 = (A-PointOnPlane)^(TriangleNormal); // Distance from A to the plane of j triangle
float D2 = (B-PointOnPlane)^(TriangleNormal);
if ((D1*D2) >= 0) continue; // Line AB doesn't cross the triangle
if (D1==D2) continue; // Line parallel to the plane
CollisionVect = A + (RayDirection) * (-D1/(D2-D1));
Vector temp;
temp = TriangleNormal*(RayDirection);
if (temp^(CollisionVect-A) < 0) continue;
temp = TriangleNormal*(C-B);
if (temp^(CollisionVect-B) < 0) continue;
temp = TriangleNormal*(A-C);
if (temp^(CollisionVect-A) < 0) continue;
// If I reach this point I had a collision //
cout << "Had collision!!" << endl;
Also I do not know exactly where exactly should this function above be called. In my render function so that it runs continuously while rendering or just once, given the fact that I only need to check for a non-moving objects collision?
I would appreciate some explanation and if you're too busy or bored to see my code, just help me with understanding a bit more this whole concept.
As suggested already, you can use bounding volumes. To make best use of these, you can arrange your bounding volumes in an Octree, in which case the volumes are boxes.
At the outermost level, each bounding volume contains the entire object. So you can test whether the two objects might intersect by comparing their zero-level bounding volumes. Testing for intersection of two boxes where all the faces are axis-aligned is trivial.
The octree will index which faces belong to which subdivisions of the bounding volume. So some faces will of course belong to more than one volume and may be tested multiple times.
The benefit is you can prune away many of the brute-force tests that are guaranteed to fail by the fact that only a handful of your subvolumes will actually intersect. The actual intersection testing is of still brute-force, but is on a small subset of faces.
Brute force collision detection often does not scale, as you have noticed. :) The usual approach is to define a bounding volume that contains your models/shapes and simplifies the intersection calculations. Bounding volumes come in all shapes and sizes depending on your models. They can be spheres, boxes, etc.
In addition to defining bounding volumes, you'll want to detect collision in your update section of code, where you are most likely passing in some delta time. That delta time is often needed to determine how far objects need to move and if a collision occurred in that timeframe.

Collision Detection and Time Complexity: How do I make checking for collisions easier?

I'm trying to write a program that handles detection of various objects. The objects have an origin, width, height, and velocity. Is there a way to set up a data structure/algorithm so that every object isn't checking with every other object?
Some sample code of the problem I'm trying to avoid:
for (int i = 0; i < ballCount; i++)
{
for (int j = i + 1; j < ballCount; j++)
{
if (balls[i].colliding(balls[j]))
{
balls[i].resolveCollision(balls[j]);
}
}
}
You can use a quadtree to quickly find all rectangles that intersect with another rectangle. If you need to handle non-rectangular shapes, you can first find objects whose bounding boxes intersect.
Some common uses of quadtrees
...
Efficient collision detection in two dimensions
...
As mentioned by other answer(s), you can use a quadtree structure to make your collision detection faster.
I would recommend the GEOS open-source C++ library, which has a good quadtree implementation. Here are the docs for their quadtree class.
So your pseudo code would look like this:
Quadtree quadtree;
// Create and populate the quadtree.
// Change it whenever the balls move.
// Here's the intersection loop:
for (int i=0; i<ballCount; ++i) {
Envelope envelope = ...; // Get the bounds (envelope) of ball i
std::vector<void*> possiblyIntersectingBalls;
quadtree.query(envelope, possiblyIntersectingBalls);
// Now loop over the members of possiblyIntersectingBalls to check
// if they really intersect, since quadtree only checks bounding
// box intersection.
}

GJK Algorithm triangle face tests

I am rebuilding my GJK algorithm but I'm having issues with triangular face tests for my tetrahedron. My point and edge tests are complete however.
I want to test if the origin is outside of the tetrahedron and closest to a particular triangular face.
So far my method was to calculate the normals of a triangular face and do a series of dot product tests to determine whether or not the origin is outside and closest to that face. My method has one main issue: I cannot guarantee my normals are facing outwards. See this figure I made for a better description:
As you can see the same triangle, depending on the ordering of the vertices requires different cross product 'ordering' to produce normals that face outwards. Is there any way for me to ensure they face outwards? If not, is there a better method for testing these faces? Here's an example of my process:
if (dot(ABC, AO) > 0) {
if (dot(ACD, AO) <= 0) {
if (dot(ADB, AO) <= 0) {
if (dot(DCB, DO) <= 0) {
// closest to face of ABC
}
}
}
}
}
Reference:
ABC, ACD, ADB, DCB = triangular face normals (as you can see I'm assuming the 'left' triangle from the picture)
AO = vector from A to origin
DO = vector from A to origin
Let's work with face ABC. Form a normal using N = cross(B-A, C-A). If dot(N, D-A) > 0, then N is inward pointing and needs to be reversed. Finally, normalize N to get a unit normal if needed.