I am currently learning about computer graphics but the topic of cyclic ordering is something that I can't seem to grasp. I was told that software like blender export the indices of triangles making up a model in a cyclic order. This way, the normals are ensured to point outward from the model.
I am not so sure what cyclic order means and how does this kind of ordering applies to triangles indices? Also, if I want to procedurally generate a mesh, what would be the algorithm I should use to apply cyclic ordering so that my mesh has correct indices for calculating normals?
Cyclic ordering means that cyclic permutations of vertex indices in a certain direction give a outward pointing normal. To illustrate this, here is a diagram:
The cylindrical arrows show the outward pointing normal. On the left is the anti-clockwise ordering convention, and on the right clockwise. The circular arrows show the directions that you can shift ("permute") the indices in, for the normal to stay the same.
For the anti-clockwise convention you would calculate the normal by (p2 - p1) x (p3 - p1), and for clockwise, (p3 - p1) x (p2 - p1). Note that the use of particular indices in these formulas is arbitrary as cyclic permutation would cover all possible ways of calculating the normal.
I don't know if one convention is more commonly used than the other (in OpenGL, for example, you are free to set either); but if it is then I would guess the anti-clockwise (2 before 3). Again - it only matters that different programs using the same data also share the same convention.
As an example, OpenGL uses the convention to determine how to calculate the outward normal, which it uses to do backface culling. It takes the dot product of the normal with a displacement vector from the camera to any point in the triangle's plane. If the result is negative then the triangle is facing the camera, and vice versa. (This is only useful for closed meshes though - you would see holes as transparent from certain angles. Again, OpenGL provides the option to disable backface culling entirely for this purpose.)
If you procedurally generate a mesh, and want to compute the correct index ordering for all triangles, do the following:
Set the per-triangle indices in any order (as long as they belong to the correct triangle)
Calculate the normal using either convention that you choose (remember to be consistent)
Use the method in my previous answer to determine whether the computed normal is facing inwards
If it is, then swap any two indices for the triangle. This will switch to the correct ordering.
Related
I've inherited some legacy code that rotates edges between triangles for improved topology distribution,
this algorithm works well but is quite computationally intensive.
The psudo-code given the quad made up of two triangles that share an edge is:
/* split 0-2 */
score_02 = (area(v0, v1, v2) / perimeter(v0, v1, v2)) +
(area(v0, v2, v3) / perimeter(v0, v2, v3));
/* split 1-3 */
score_13 = (area(v1, v2, v3) / perimeter(v1, v2, v3)) +
(area(v0, v1, v3) / perimeter(v0, v1, v3));
/* negative number when (0-2) is an improved state */
result = score_13 - score_02;
This works very well and can give nice tessellation on 2D triangulated regions (see example).
My main concern is this is not very efficient (perimeter calculations involve 6 square-root calls).
Are there other/better methods to calculate a relaxed state before (above), after relaxation (below), eg:
Failing to use a good method may:
Cause one of the triangles to have zero area(depending on what the output is used for, this may have cascading effects - faces with zero area normals for example aren't as easily handled when using as input for other processes).
Poor divisions may cause distortion of mapped textures or deform badly.
It's been pointed out (in an answer that is now deleted) that a simple shortest-edge method can be used, however this doesn't give a good distribution (notice the skinny triangles at the boundaries) eg:
Note 1) that this may be a well known problem, since it wasn't documented in the
code, its not an easy thing to search for :)
Note 2) so far I didn't seriously look into an alternative method, I may do so and post findings here.
You can try producing a constrained delaunay triangulation. This is the "nicest" (provable) triangulation you may have for a given point set.
If you can add more points (without changing the shape) to the interior or the edges (called steiner points), you can guarantee better triangles (in terms of minimum interior angles and area).
See: http://www.cs.cmu.edu/~quake/triangle.defs.html#conform.
CGAL has implementations for these.
The code you posted makes a decision "to flip or not to flip" the shared edge between to triangles. It choses the most regular triangle (equilateral is the best) of the two possibilities: with or without edge-flip.
This "most regular" criterium is based in the relation area/perimeter. You don't need a value; just just need the sign of the option1 - option2 result.
So you don't need square-roots. Using the squared terms is enough.
A bit of performance improve can be checked if you use Heron's formula for the area. You can calculate first the square of the perimeter and use it in that formula.
Other way of achieving better regular triangles is using Delaunay condition, which produces the maximal area with the same perimeter. The test meat is flipping an edge if the fourth point is inside the circumcircle defined by the other three points.
The typical name for this test is "InCircle". It's the result of a determinant (see it at the Wikipedia). The three points must be entered in counterclockwise order, or the sign of the determinant changes. The only drawback of this determinant is its numerical issue when the three points are near co-linear.
I am trying to write a Rigid body simulator, and during simulation, I am not only interested in finding whether two objects collide or not, but also the point as well as normal of collision. I have found lots of resources which actually says whether two OBB are colliding or not using separating axis theorem. Also I am interested in 3D representation of OBB. Now, if I know the axis with minimum overlap region for two colliding OBB, is there any way to find the point of collision and normal of collision? Also, there are two major cases of collision, first, point-face and second edge-edge.
I tried to google this problem, but almost every solution is only detecting collision with true or false.
Kindly somebody help!
Look at the scene in the direction of the motion (in other terms, apply a change of coordinates such that this direction becomes vertical, and drop the altitude). You get a 2D figure.
Considering the faces of the two boxes that face each other, you will see two hexagons each split in three parallelograms.
Then
Detect the intersections between the edges in 2D. From the section ratios along the edges, you can determine the actual z distances.
For all vertices, determine the face they fall on in the other box; and from the 3D equations, the piercing point of the viewing line into the face plane, hence the distance. (Repeat this for the vertices of A and B.)
Comparing the distances will tell you which collision happens first and give you the coordinates of the first meeting point (in the transformed system, the back to absolute coordinates).
The point-in-face problem is easy to implement as the facesare convex polygons.
Given two 3d objects, how can I find if one fits inside the second (and find the location of the object in the container).
The object should be translated and rotated to fit the container - but not modified otherwise.
Additional complications:
The same situation - but look for the best fit solution, even if it's not a proper match (minimize the volume of the object that doesn't fit in the container)
Support for elastic objects - find the best fit while minimizing the "distortion" in the objects
This is a pretty general question - and I don't expect a complete solution.
Any pointers to relevant papers \ articles \ libraries \ tools would be useful
Here is one perhaps less than ideal method.
You could try fixing the position (in 3D space) of 1 shape. Placing the other shape on top of that shape. Then create links that connect one point in shape to a point in the other shape. Then simulate what happens when the links are pulled equally tight. Causing the point that isn't fixed to rotate and translate until it's stable.
If the fit is loose enough, you could use only 3 links (the bare minimum number of links for 3D) and try every possible combination. However, for tighter fit fits, you'll need more links, perhaps enough to place them on every point of the shape with the least number of points. Which means you'll some method to determine how to place the links, which is not trivial.
This seems like quite hard problem. Probable approach is to have some heuristic to suggest transformation and than check is it good one. If transformation moves object only slightly out of interior (e.g. on one part) than make slightly adjust to transformation and test it. If object is 'lot' out (e.g. on same/all axis on both sides) than make new heuristic guess.
Just an general idea for a heuristic. Make a rasterisation of an objects with same pixel size. It can be octree of an object volume. Make connectivity graph between pixels. Check subgraph isomorphism between graphs. If there is a subgraph than that position is for a testing.
This approach also supports 90deg rotation(s).
Some tests can be done even on graphs. If all volume neighbours of a subgraph are in larger graph, than object is in.
In general this is 'refined' boundary box approach.
Another solution is to project equal number of points on both objects and do a least squares best fit on the point sets. The point sets probably will not be ordered the same so iterating between the least squares best fit and a reordering of points so that the points on both objects are close to same order. The equation development for this is a lot of algebra but not conceptually complicated.
Consider one polygon(triangle) in the target object. For this polygon, find the equivalent polygon in the other geometry (source), ie. the length of the sides, angle between the edges, area should all be the same. If there's just one match, find the rigid transform matrix, that alters the vertices that way : X' = M*X. Since X' AND X are known for all the points on the matched polygons, this should be doable with linear algebra.
If you want a one-one mapping between the vertices of the polygon, traverse the edges of the polygons in the same order, and make a lookup table that maps each vertex one one poly to a vertex in another. If you have a half edge data structure of your 3d object that'll simplify this process a great deal.
If you find more than one matching polygon, traverse the source polygon from both the points, and keep matching their neighbouring polygons with the target polygons. Continue until one of them breaks, after which you can do the same steps as the one-match version.
There're more serious solutions that're listed here, but I think the method above will work as well.
What a juicy problem !. As is typical in computational geometry this problem
can be very complicated with a mismatched geometric abstraction. With all kinds of if-else cases etc.
But pick the right abstraction and the solution becomes trivial with few sub-cases.
Compute the Distance Transform of your shapes and VoilĂ ! Your solution is trivial.
Allow me to elaborate.
The distance map of a shape on a grid (pixels) encodes the distance of the closest point on the
shape's border to that pixel. It can be computed in both directions outwards or inwards into the shape.
In this problem, the outward distance map suffices.
Step 1: Compute the distance map of both shapes D_S1, D_S2
Step 2: Subtract the distance maps. Diff = D_S1-D_S2
Step 3: if Diff has only positive values. Then your shapes can be contained in each other(+ve => S1 bigger than S2 -ve => S2 bigger than S1)
If the Diff has both positive and negative values, the shapes intersect.
There you have it. Enjoy !
Given a point and a set of arbitrary 2D entities (circles, polygons, lines, polylines, arcs, etc.), does anyone know of existing strategies to:
Determine if the point is enclosed (bounded) by any combination of entities? I know that it is easy enough to do an 'inside' test on the closed shapes, but this won't always give me what I want - particularly with nested or intersecting shapes.
Find the smallest (closest?) set of lines / entities that form a closed polygon around my point? (think of a flood-fill, but without relying on colour)
I've addressed this problem in a commercial product in the past. You've asked about analytic curves, but I'll address it more generally for curves that are at least twice differentiable. Handle polygons as a set of separate line segments. There is no need to segment the curves, but if you want to you can and adapt the algorithm slightly.
Also, you might want to see my paper Matrix-Based Ellipse Geometry in Graphics Gems V to find the intersections between your ellipses.
Basic idea:
Consider a ray from your test point in the +x direction.
Now consider an ant walking along your ray from the test point.
When the ant hits the first intersection with one of the curves, it makes the sharpest left it can, and leaves an arrow at that intersection indicating the direction it's chosen. (If there is no intersection, then obviously the point isn't bounded.)
If it comes to the end of a curve, it doubles back on itself.
If there are multiple curves intersecting at that point, it chooses the curve that is most to the left.
If one or more of the curves is in fact tangent to the ray at the intersection, higher derivatives can be used decide which curve and direction to choose. (This ant knows calculus.)
Now as the ant strolls along the curves, it always makes the biggest left turn it can as above. If there is tangency between curves at the intersection, use higher derivatives to decide the one that is "most to the left". (Details are left to the ant).
In its travels, the ant may come to the starting intersection with the ray multiple times. But as soon as it finds itself proceeding in the direction of the arrow (the one it left in step 3), it's travels are done and it has traversed a "contour". The problem is reduced to deciding if the point is in that contour.
A "contour" is a topological entity. It's closed ring of "segments" connected at "vertices".
A "segment" is a piece of a curve used by the contour in a particular direction.
A "vertex" is a connection between segments. A vertex is associated with a (x, y) position on the plane, but there may be multiple vertices at the same position, one for each pair of segments in the contour that meet at that point. There is a vertex for each curve endpoint (a spur vertex), or curve-curve intersection encountered by the ant.
A contour (in this context) is not a geometric entity! Don't think of it as a simple closed path on the plane. The ant might go along a segment, get to the end, and go back the way it came--this is called a "spur" and includes two contour segments, one for either direction. Or it might go along one direction of a curve segment, wander around a bit along other curves, and return along the other direction of the segment.
So even if your set of curves has only one line in it from A to B (I'm assuming you don't have infinite lines) and your ray hits it at P, you still have the contour V0(P)-V1(A)-V2(P)-V3(B)-V0 with 4 segments V0-V1, V1-V2, V2-V3, V3-V0. Note that V0 and V2 are distinct vertices, both positioned at P.
Now to test if your point is in the contour.
Find the intersections of your ray (any ray originating at your test point will do) with the contour. We only really want the parity (even or odd) of the number of intersections with the contour. If the parity is odd, the point is bounded by the curves, if it's even it's not.
Because doubly traversed segments contribute nothing to the parity, we can ignore them. This is because there are always an even number of intersections on doubly traversed segments, since they're in the contour twice.
Examples:
Consider this curve set. I use lines so I don't work too hard:
Case 1 - The point is not bounded. The contour's use of the curve segments is indicated by the dotted arrows. The number of ray-contour intersection parity is even.
Case 2 - The point is bounded. The ray-contour intersection parity is odd.
Here's what can go wrong:
You can't find a contour for various numerical reasons. For example, you might miss intersections, e.g. two curves are almost tangent at a curve. You might see it as a single intersection, but when you do the ray intersection parity test you see a single crossing so that the parity flips when it shouldn't.
You might not be able to compute enough derivatives to make the correct turn decisions. In the case of analytic geometry this should never be the case.
Your ray hits a vertex (connections between segments) of your contour. (Note that there can be multiple vertices at a single (x, y) point. Each of these has to be handled separately.)
In this case, you have to decide if the incoming and outgoing segments of the vertex are on the same side of the ray at the vertex. If they're on the same side, the parity is not affected. Otherwise the parity flips. If one of the curves is tangent to the ray at the vertex, you may have to use higher derivatives to decide this.
A line segment is collinear with your test ray. This is actually a special case of 2, but easy to handle: Ignore it.
There are lots of details, but you should be able to handle them. Be sure to use spatial trees to avoid computing unnecessary intersections.
The answer to your second question comes from removing from the contour any doubly traversed segments. This may yield multiple sub-contours. One of them will contain your point.
Here is a problem I am trying to solve:
I have an irregular shape. How would I go about evenly distributing 5 points on this shape so that the distance between each point is equal to each other?
David says this is impossible, but in fact there is an answer out of left field: just put all your points on top of each other! They'll all have the same distance to all the other points: zero.
In fact, that's the only algorithm that has a solution (i.e. all pairwise distances are the same) regardless of the input shape.
I know the question asks to put the points "evenly", but since that's not formally defined, I expect that was just an attempt to explain "all pairwise distances are the same", in which case my answer is "even".
this is mathematically impossible. It will only work for a small subset of base shapes.
There are however some solutions you might try:
Analytic approach. Start with a point P0, create a sphere around P0 and intersect it with the base shape, giving you a set of curves C0. Then create another point P1 somewhere on C0. Again, create a sphere around P1 and intersect it with C0, giving you a set of points C1, your third point P2 will be one of the points in C1. And so on and so forth. This approach guarantees distance constraints, but it also heavily depends on initial conditions.
Iterative approach. Essentially form-finding. You create some points on the object and you also create springs between the ones that share a distance constraint. Then you solve the spring forces and move your points accordingly. This will most likely push them away from the base shape, so you need to pull them back onto the base shape. Repeat until your points are no longer moving or until the distance constraint has been satisfied within tolerance.
Sampling approach. Convert your base geometry into a voxel space, and start scooping out all the voxels that are too close to a newly inserted point. This makes sure you never get two points too close together, but it also suffers from tolerance (and probably performance) issues.
If you can supply more information regarding the nature of your geometry and your constraints, a more specific answer becomes possible.
For folks stumbling across here in the future, check out Lloyd's algorithm.
The only way to position 5 points equally distant from one another (other than the trivial solution of putting them through the origin) is in the 4+ dimensional space. It is mathematically impossible to have 5 equally distanced object in 3D.
Four is the most you can have in 3D and that shape is a tetrahedron.