Surface subdivision into equal parts - geometry-surface

I have a closed contour represented by a list of points and I need to split it into equal parts, knowing the area of the parts.
I think that I can use some subdivision algorithm, like Delanuy subdivision. But with this method I have to give the centroid of the subdivded parts.
Anyone has some hints?

if i understand correctly: given say a rectangle say of area 10, and a target area of 1, you would need to partition rectangle into 10 parts, each having area of 1. So slicing the rectangles into 10 thin rectangles (like guitar frets, or bread slices) would do.
If that's the case, then I would do the following:
Create a function to compute the area of a convex poly. This is fairly trivial (since poly is convex).
Observe, since input poly is convex, any line segment that splits the polygon into two, will intersect the polygon in exactly two places. Specifically, you can triangulate the polygon by picking a vertex of the poly and connecting it to every other vert of the polygon, like a fan.
Triangulating in this fashion would create a partition that would be close to what you need. Assume that the input polygon is given by a vertex list poly = {v1, v2, v3, ..., vn}, where verts are unique and no three are co-linear (convex poly).
Observe that given a triangle of that poly formed by say (v2,v3,v4) we can compute its area, A1. Now if we grow the triangle into a poly by adding one extra vert to the next, say v5, to form (v2, v3, v4, v5) the area increased to A2 (sum of two triangles, (v2,v3,v4) and (v2,v4,v5). Due to linearity if you wanted to grow the original triangle to say A2' where A1 < A2' < A2, you can interpolate on the line segment (v4,v5) to find v4' that will give you the right area A2' that you need.
Since you can compute the total area of initial input poly, and you know the target area of each subdivision, you can cut the input poly into pieces of desired area until you subdivide the entire thing. If you want a nicer partition, you can start from the center of the polygon, i.e. first (seed triangle) would be (center, v1,v2). Then shrink/grow it until desired area, move to the next triangle, repeat.
Hope that makes sense :D

Related

Snapping vector to a point from a grid on a sphere (icosahedron)

here is a problem that will turn your brain inside out, I'm trying to deal with it for a quite some time already.
Suppose you have sphere located in the origin of a 3d space. The sphere is segmented into a grid of equidistant points. The procedure that forms grid isn't that important but what seems simple to me is to use regular 3d computer graphics sphere generation procedure (The algorithm that forms the sphere described in the picture below)
Now, after I have such sphere (i.e. icosahedron of some degree) I need a computationally trivial procedure that will be capable to snap (an angle) of a random unit vector to it's closest icosahedron edge points. Also it is acceptable if the vector will be snapped to a center point of triangle that the vector is intersecting.
I would like to emphasise that it is important that the procedure should be computationally trivial. This means that procedures that actually create a sphere in memory and then involve a search among every triangle in sphere is not a good idea because such search will require access to global heap and ram which is slow because I need to perform this procedure millions of times on a low end mobile hardware.
The procedure should yield it's result through a set of mathematical equations based only on two values, the vector and degree of icosahedron (i.e. sphere)
Any thoughts? Thank you in advance!
============
Edit
One afterthought that just came to my mind, it seems that within diagram below step 3 (i.e. Project each new vertex to the unit sphere) is not important at all, because after bisection, projection of every vertex to a sphere would preserve all angular characteristics of a bisected shape that we are trying to snap to. So the task simplifies to identifying a bisected sub triangle coordinates that are penetrated by vector.
Make a table with 20 entries of top-level icosahedron faces coordinates - for example, build them from wiki coordinate set)
The vertices of an icosahedron centered at the origin with an
edge-length of 2 and a circumscribed sphere radius of 2 sin (2π/5) are
described by circular permutations of:
V[] = (0, ±1, ±ϕ)
where ϕ = (1 + √5)/2
is the golden ratio (also written τ).
and calculate corresponding central vectors C[] (sum of three vectors for vertices of every face).
Find the closest central vector using maximum of dot product (DP) of your vector P and all C[]. Perhaps, it is possible to reduce number of checks accounting for P components (for example if dot product of P and some V[i] is negative, there is no sense to consider faces being neighbors of V[i]). Don't sure that this elimination takes less time than direct full comparison of DP's with centers.
When big triangle face is determined, project P onto the plane of that face and get coordinates of P' in u-v (decompose AP' by AB and AC, where A,B,C are face vertices).
Multiply u,v by 2^N (degree of subdivision).
u' = u * 2^N
v' = v * 2^N
iu = Floor(u')
iv = Floor(v')
fu = Frac(u')
fv = Frac(v')
Integer part of u' is "row" of small triangle, integer part of v' is "column". Fractional parts are trilinear coordinates inside small triangle face, so we can choose the smallest value of fu, fv, 1-fu-fv to get the closest vertice. Calculate this closest vertex and normalize vector if needed.
It's not equidistant, you can see if you study this version:
It's a problem of geodesic dome frequency and some people have spent time researching all known methods to do that geometry: http://geo-dome.co.uk/article.asp?uname=domefreq, see that guy is a self labelled geodesizer :)
One page told me that the progression goes like this: 2 + 10·4N (12,42,162...)
You can simplify it down to a simple flat fractal triangle, where every triangle devides into 4 smaller triangles, and every time the subdivision is rotated 12 times around a sphere.
Logically, it is only one triangle rotated 12 times, and if you solve the code on that side, then you have the lowest computation version of the geodesic spheres.
If you don't want to keep the 12 sides as a series of arrays, and you want a lower memory version, then you can read about midpoint subdivision code, there's a lot of versions of midpoint subdivision.
I may have completely missed something. just that there isn't a true equidistant geodesic dome, because a triangle doesn't map to a sphere, only for icos.

How to Judge the Equality of 2 Triangular Meshes?

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.

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.

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.

Finding a stable placement of an irregular (non-convex) shape

Given an image of a 2-dimensional irregular (non-convex) shape, how would I able to compute all the ways in which it could lie stable on a flat surface? For example, if the shape is a perfect square rectangle, then it will surely have 4 ways in which it is stable. A circle on the other hand either has no stable orientation or every point is a stable orientation.
EDIT: There's this nice little game called Splitter (Beware, addictive game ahead) that seems close to what I want. Noticed that you cut a piece of the wood out it would fall to the ground and lay in a stable manner.
EDIT: In the end, the approach I took is to compute center of mass (of the shape) and compute the convex hull (using OpenCV), and then loop through every pair of vertices. If the center of mass falls on top of the line formed by the 2 vertices, it is deemed stable, else, no.
First find its center of mass (CM). A stable position is one in which the CM will be higher if you make a slight rotation. Now look at the hull, the smallest convex region that encloses the shape:
(source: walkytalky.net)
If the hull is a polygon, then a stable position is one in which the shape is resting on one of the sides, and the CM is directly over that side (not necessarily over the midpoint of the side, just somewhere over it.
If the hull has curves (that is, if the shape has curves which touch the hull), they must be give special treatment. The shape will be stable when resting on a curved edge iff the CM is directly above the lowest point of the curve, and the radius of the curve at that point is greater than the height of the CM.
Examples:
A rectangle. The hull is simply the rectangle, and the CM is at the center. The shape is stable on each of the four sides.
A rectangle with the sides hollowed, but the corners still intact. The hull is still the original rectangle, and the CM is close to where it used to be. All four sides of the hull are still stable (that is, you can still rest the shape on any two corners).
A circle. The CM is in the center, the hull is the circle. There are no stable positions, since the radius of the curve is always equal to the height of the CM. Give it a slight touch, and it will roll.
An ellipse. The CM is at the center, the hull is the shape. Now there are two stable positions.
A semicircle. The CM is somewhere on the axis of symmetry, the hull is the shape. Two stable positions.
A narrow semicircular crescent. The hull is a semicircle, the CM is outside the shape (but inside the hull). Two stable positions.
(source: walkytalky.net)
(The ellipse position marked with an X is unstable, because the curvature is smaller than the distance to the centre of mass.)
note: this answer assumes your shape is a proper polygon.
For our purposes, we'll define an equilibrium position as one where the Center of Mass is directly above a point that is between the leftmost and rightmost ground-contact points of the object (assuming the ground is a flat surface perpendicular to the force of gravity). This will work in all cases, for all shapes.
Note that, this is actually the physical definition of rotational equilibrium, as a consequence of Newtonian Rotational Kinematics.
For a proper polygon, if we eliminate cases where they stand on a sole vertex, this definition is equivalent to a stable position.
So, if you have a straight downward gravity, first find the left-most and right-most parts of it that are touching the ground.
Then, calculate your Center of Mass. For a polygon with known vertices and uniform density, this problem is reduced to finding the Centroid (relevant section).
Afterwards, drop a line from your CoM; if the intersection of the CoM and the ground is between those two x values, it's at equilibrium.
If your leftmost point and rightmost point match (ie, in a round object), this will still hold; just remember to be careful with your floating point comparisms.
Note that this can also be used to measure "how stable" an object is -- this measure is the maximum y-distance the Center of Mass can move before it is no longer within the range of the two contact points.
EDIT: nifty diagram made hastily
So, how can you use this to find all the ways it can sit on a table? See:
EDIT
The programmable approach
Instead of the computationally expensive task of rotating the shape, try this instead.
Your shape's representation in your program should probably have a list of all vertices.
Find the vertices of your shape's convex hull (basically, your shape, but with all concave vertices -- vertices that are "pushed in" -- eliminated).
Then Iterate through each of pair of adjacent vertices on your convex hull (ie, if I had vertices A, B, C, D, I'd iterate through AB, BC, CD, DA)
Do this test:
Draw a line A through the two vertices being tested
Draw a line perpendicular to A, going through CoM C.
Find the intersection of the two lines (simple algebra)
If the intersection's y value is in between the y value of the two vertices, it stable. If the y values are all equal, compare the x values.
That should do the trick.
Here is an example of the test being running on one pair of vertices:
If your shape is not represented by its vertices in your data structure, then you should try to convert them. If it's something like a circle or an ellipse, you may use heuristics to guess the answer (a circle has infinite equilibrium positions; an ellipse 4, albeit only two "stable" points). If it's a curved wobbly irregular shape, you're going to have to supply your data structure for me be able to help in a program-related way, instead of just providing case-by-case heuristics.
I'm sure this is not the most efficient algorithm, but it's an idea.
If you can order the verticles of the polygon (assuming it has a finite number of vertices), then just iterate over adjacent pairs of vertices and record the angle it rests at through some form of simulation. There will be duplicate orientations for it to sit on in the case of weird shapes, like stars, but you can accomodate for that by keeping track of the resting rotation.

Resources