How to Judge the Equality of 2 Triangular Meshes? - algorithm

Given a triangular mesh A in 3D space. Rotate and translate all its points to generate a new mesh B.
How to determine the equality of A and B, just by their vertices and faces?
Topology of the mesh is not important, I only care about the geometric equality, A and B should be equal even if their triangulation are changed. It is
something like the transform in-variance problem for triangular mesh, only translate and rotation is considered.

To complete #Spektre's answer, if the two meshes are not exactly the same, that is there is at least a pair of nodes or edges which does not perfectly overlap, You can use the Hausdorff distance to quantify the "difference" between the two meshes.

Assuming triangle faces only.
compare number of triangles
if not matching return false.
sort triangles by their size
if the sizes and order does not match between both meshes return false.
find distinct triangle in shapes
So either the biggest or smallest in area, edge length or whatever. If not present then you need other distinct feature like 2 most distant points etc ... If none present even that then you need the RANSAC for this.
Align both meshes so the matching triangles (or feature points) will have the same position in both meshes.
compare matching vertexes
so find the closest vertex form Mesh A to each vertex in mesh B and if the distance of any them cross some threshold return false
return true
In case meshes has no distinct features for 3 you need to either use brute force loop through all combinations of triangles form A and B until #4 returns true or all combinations tested or use RANSAC for this.
There are alternatives to #3 like find the centroid and closest and farthermost points to it and use them as basis vectors instead of triangle. that requires single vertex or close group of vertexes to be the min and max. if not present like in symmetrical meshes like cube icosahedron, sphere you're out of luck.
You can enhance this by using other features from the mesh if present like color, texture coordinate ...
[Edit1] just a crazy thinking on partial approach without the need of aligninig
compute average point C
compute biggest inscribed sphere centered at C
just distance from C to its closest point
compute smallest outscribed sphere centered at C
just distance from C to its farthest point
compare the radiuses between the shapes
if not equal shapes are not identical for sure. If equal then you have to check with approaches above.

The paper On 3D Shape Similarity (Heung-yeung Shum, Martial Hebert, Katsushi Ikeuchi) computes a similarity score between two triangular meshes by comparing semiregular sphere tessellations that have been deformed to approximate the original meshes.
In this case, the meshes are expected to be identical (up to some small error due to the transformation), so an algorithm inspired by the paper could be constructed as follows:
Group the vertices of each mesh A, B by the number of neighboring vertices they have.
Choose one vertex V_A from mesh A and vertex V_Bi from mesh B, both with same number of neighbors.
The vertex and its N neighbors V_n1...V_nN form a triangle fan of N triangles. Construct N transforms which take vertex V_Bi to V_A and each possible fan (starting from a different neighbor V_Bn1, V_Bn2, ..., V_BnN) to V_An1...V_AnN.
Find the minimum of the sums of distances from each vertex of B to the closest vertex to it in A, for each N transforms for each vertex V_Bi.
If a sum of near zero is found, the vertices of the transformed mesh B coincide with vertices of A, a mapping between them can be constructed, and you can do further topological, edge presence or direction checks, as needed.

Related

Translate and transform plane geometry based on corner coordinates

I have a plane mesh with divisions and I want to specify the coordinates that each of the corners should be positioned. Moving and updating the mesh vertices achieves what I'm trying to do, so long as the plane only has no internal segments. If internal segments are added then I have more vertices than I can manually place, so these need to automatically fall in line with the transformation of the outer edges.
My initial thought here was that I could create a geometry with only four vertices, reposition them, and then increase the number of segments on my plane, apparently, this isn't something that Three.js supports, so I'm looking for a workaround.
Any thoughts would be appreciated.
I don't think that this sort of transformation is expressible as a single matrix that you could then just apply to your plane mesh. I think you really do need to calculate the coordinates of each vertex of the subdivided plane manually.
There are different ways to do this calculation. Bilinear interpolation is this case seems to do the job. Here's how you do it. If you have four points A, B, C, D, then for each internal points, its position can be found as the weighted average of (the weighted average of A and B, and the weighted average of C and D). The weights for the averages come from the index of the subdivision vertex in one direction (say, X) for the inner averages and in the other direction (say, Y) for the outer average. Your indexes run from 0 up to the number of subdivisions in that direction (inclusive), the weight should be from 0 to 1, so the weight = index / number of subdivisions.

Project 3D polygon into a 2D plane such that the vertices are in counter clockwise order

Some fast algorithms for working with polygons require the vertices of the polygon to have a specific order (clockwise or counter clockwise with respect to the polygon's plane normal).
To use those algorithms in 3D planar polygons (where all the points lie in a particular plane) one can perform a change of basis to a basis spanned by two orthogonal vectors that lie in the plane and a plane normal vector.
Is there a way to always find a basis in which the polygon vertices are always in counter clockwise (or clockwise) order?
Perhaps the best method is to compute the signed area of the polygon, and if it is negative, you know your vertices are clockwise; so reverse. If it is positive, your vertices are counterclockwise.
Search for "signed area of polygon." Here is one Mathematica link:

A plane subdivision into non-overlapping regions by a set of polygons

Please see the example image:
There are a set of polygons (convex, non-convex, but not self-intersecting) in a plane. Polygon is defined by vertices – points (x and y coordinates, cartesian coordinate system).
Example set of polygons:
The first polygon is A, B, C.
The second polygon is D, E, F, G, H, I, J.
The third polygon is K, L, M, N.
The fourth polygon is O, P, Q.
Polygons divide a plane into regions. Some parts of polygons may be overlapping (like the first and the second polygon, the second polygon and the third polygon). This overlapping parts is seperate regions too. Some polygons may be inside others (like the fourth polygon inside the second polygon).
Example regions after subdivision: blue, pink, green, orange, brown and purple.
I imagine for simplicity that the plane is a rectangle with constant x, y coordinates.
The Goal
Detect the region (blue, pink, green, etc.) by the query point.
I am looking for algorithm and data structure for a plane subdivision with these assumptions.
First transform your set of polygons into a set of non-overlapping polygons by iteratively looking for pairwise intersections and replacing the pair of intersecting polygons with their intersection and the original polygons minus the intersection. This might be easier and faster if you first split each polygon into a set of convex polygons (the convex polygons can simply "inherit" the "color" of the original concave polygon).
You can then put the polygons into a quad-tree or a similar data structure which allows you to quickly select candidate polygons for membership tests for a given query point.
You will need to define what is happening on edges shared between multiple polygons.
I can recommend a trapezoidal decomposition http://en.wikipedia.org/wiki/Point_location#Trapezoidal_decomposition for efficient point queries in a planar subdivision.
In your case, the subdivision is defined indirectly so there is an extra step. You can try three approaches:
1) use a general polygon intersection algorithm that you will call incrementally,
2) form the trapezoidal decompositions of the polygons and perform fusions of these trapezoidal maps,
3) modify an existing trapezoidal decomposition algorithm so that it accepts as input a subdivision formed of overlapping polygons.
You will need to use some 2D Computational Geometry library... and courage.
ALTERNATIVE:
If your precision requirements are not too high, use a bitmap and fill every polygon, changing the color when pixels already painted are met.

How to efficient extract new polygons form the exist polygons

the polygons image
All of the polygons are simply, there are no holes in them.
board polygon(P0 to P7)
Red polygon (R0 to R6)
Green polygon (G0 G1 P2 G3)
Yellow polygon(Y0 to Y3)
I want to got new four polygons marked as 1 to 4 , polygon 1's coordinates are(J7 J10 R5 R4).
When I use polygon clipping algorithm, I can got the results easy , board diff(red union green union yellow). But when I have more than 10,000 polygons, I need a long time to get my results. My polygons are simply and my result polygons are simply also, there are no holes in the result polygons also.
You know I can find out the four polygons form the image easy using eyes, but how to find them using algorithm.
Thanks.
If all vertices of your computed black polygons do not have more than 2 edges intersecting at the vertex, then there may be a faster way than a more general tool.
Since the number of polygons is on the order of 10000, first try computing the intersection points of all pairs of polygons, and hopefully the number of intersection points is small enough (like 10 million or less). Then, for each intersection point test to see if it is contained in the interior of another polygon (in case you have multiple polygons that jointly overlap). Testing to see if a point is contained in the interior of a polygon can be done quickly, you can read how online. Then, all intersection points that are not contained in another polygon, which note also contains all the original polygon vertices that are not contained in the interior of a polygon, these are the vertices for the "black" polygons you want to compute. These points should be stored with a secondary structure that for each polygon edge, it stores all the stored intersection points along that edge, in sorted order. Similarly, for each stored vertex and intersection point you should store the edges that intersect at that point, and the location of the intersection point in the previous structure. So then pick any stored intersection point that hasn't been used yet in a black polygon, and pick one edge that defines the intersection point. Then you move to the neighboring intersection point along the edge which has the property that the part of the edge between the two intersection points does not pass inside a polygon. Then continue by similarly moving along the other edge that defines the neighboring intersection point. Continue until you reach the vertex you started at; this defines one black polygon. Then you can pick a new unused stored intersection point and repeat. Since your polygons have no holes, this will find all black polygons.

Most efficient algorithm to calculate vertex normals from set of triangles for Gouraud shading

We are given a set of triangles. Each triangle is a triplet of points. Each point is a triplet of real numbers. We can calculate surface normal for each triangle. For Gouraud shading however, we need vertex normals. Therefore we have to visit each vertex and look at the triangles that share that vertex, average their surface normals and we get vertex normal.
What is the most efficient algorithm and data structure to achieve this?
A naive approach is this (pseudo python code):
MAP = dict()
for T in triangles:
for V in T.vertices:
key = hash(V)
if MAP.has(key):
MAP[key].append(T)
else:
MAP[key] = []
MAP[key].append(T)
VNORMALS = dict()
for key in MAP.keys():
VNORMALS[key] = avg([T.surface_normal for T in MAP[key]])
Is there a more efficient approach?
Visit each triangle, calculate the normal for each triangle, ADD those to the vertex normal for each corner vertex.
Then at the end, normalise the normals for each vertex.
Then at least you only have to traverse the triangles once and you only store one normal/vertex.
Each vertex belongs to one or more faces (usually triangles, sometimes quads -- I'll use triangles in this answer).
A triangle that is not attached to any other triangles cannot be 'smoothed'. It is flat. Only when a face has neighbours can you reason about smoothing them together.
For a vertex where multiple faces meet, calculate the normals for each of these faces. The cross product of two vectors returns a perpendicular (normal) vector, which is what we want.
A --- B
\ /
C
v1 = B - A
v2 = C - A
normal = v1 cross v2
Be careful to calculate these vectors consistently across all faces, otherwise your normal may be in a negative direction to that you require.
So at a vertex where multiple faces meet, sum the normals of the faces, normalise the resulting vector, and apply it to the vertex.
Sometimes you have a mesh where some parts of it are to be smoothed, and others not. An easy to picture example is a cylinder made of triangles. The round surface of the cylinder would smooth well, but if you consider triangles from the flat ends at the vertices around the sharp ridge, it will look strange. To avoid this, you can introduce a rule that ignore normals from faces which deviate too far from the normal of the face you're calculating for.
EDIT there's a really good video showing technique for calculating Gourad shading, though it doesn't discuss an actual algorithm.
You might like to take a look at the source of of Three.js. Specifically, the computeVertexNormals function. It does not support maintaining sharp edges. The efficiency of your algorithm depends to a large extent upon the way in which you are modelling your primitives.

Resources