Find the slice cut by a line segment, an origin point on a 3D polygon - algorithm

I have an array of triangle vertices (faces of the polygon), something like
[[[a, b, c], [d, e, f], [g, h, i]], ...]
I have a line segment, represented by 2 3D vertices, let's say [[j, k, l], [m, n, o]].
And I have a point [p, q, r].
What I want to do is, project the point on the polygon, through the line segment, and check if it completely slices the polygon (I think 4 points of contact should be enough? I could be wrong). And if it does, I need all the points of intersection which lie on the edges and vertices.
I'm completely lost here. Any pointers would be appreciated.

We can assume without loss of generality that the triangle formed by the point & line segment (henceforth T) lies in the x-y plane. (Otherwise, rotate everything appropriately).
We loop through the triangle faces, for any pair of vertices of a face where their y-coordinates have different signs (i.e. for any edge that cuts the x-y plane), we check the intersection of the edge with the x-y plane and make sure it's within T.
It holds that T "completely slices the polygon" if and only if all such checks are true.
Running time is O(number of faces).
All the operations described are pretty simple. E.g. Checking that something is in the bounds of T is simply checking two inequalities with the equations of the two lines that define T (i.e. from the point to the end points of the line segment).
All POI with the edges (and thus vertices) can be calculated within the loop - it's simply the POI of the edge with the x-y plane.

Related

Maximum enclosing disk

Let A and B be two sets of points, each consisting of n points, all lying in unit square S.
I am trying to find a efficient algorithm for finding the largest disk D such that:
(i) The center of D lie in S.
(ii) The interior of D is empty.
(iii) The boundary of D touches atleast one point from A and one point from B.
Im having a real problem with this question. Any hints will be usefull.
To complete Yves Daoust's partial solution, compute the Voronoi diagram (which is dual to the Delaunay triangulation) bounded by S. We can find an optimal circle center at some Voronoi vertex (i.e., a point in the interior of S where the nearest three points in A ∪ B are equidistant, or a point on the boundary of S where the nearest two points in A ∪ B are equidistant) where one of the nearest points is in A and another is in B.
Such a vertex is clearly feasible as a center. If we try to take any other center, then we can apply stark's observation. This center must be equidistant from a point in A and a point in B, so assuming that A ∩ B is empty (I really don't want to think about the degenerate cases; we can always perturb our way out), we can slide the center along the perpendicular bisector of AB until we hit either a third point or the boundary.

Analytic geometry, ordering vertices of triangle to capture shortes and second sortest sides

If I have x and y coordinates for triangle corners A, B, and C, I want to know which of the six orderings of {A, B, C} put the shortest side of the triangle between the first two vertices in the ordering, and the second shortest side between the last two. I know how to solve this, but not in a way that isn't clumsy and inelegant and all around ugly. My favorite language is Ruby, but I respect all of them.
As the third side of a triangle cannot be deduced from the other two, you must compute the three distances.
As the three points may require to be permuted in one of six ways, you cannot work this out with a decision tree that has less than three levels (two levels can distinguish at most four cases).
Hence, compute the three distances and sort them increasingly using the same optimal decision tree as here: https://stackoverflow.com/a/22112521/1196549 (obviously their A, B, C correspond to your distances). For every leaf of the tree, determine what permutation of your points you must apply.
For instance, if you determine |AB|<|CA|<|BC|, you must swap A and B. Solve all six cases similarly.
Doing this you will obtain maximally efficient code.
If you are completely paranoid like I am, you can organize the decision tree in such a way that the cases that require a heavier permutation effort are detected in two tests rather than three.
Here's how I would do it: let's take a triangle with sides x, y, and z, such that l(x) <= l(y) <= l(z). Then, let x', y', and z' be the vertices opposite to x, y, and z, respectively.
Your output will be y', z', x' (if you draw out your triangle, you'll see that this is the order which achieves your requirement). So, the pseudocode looks like:
For points a, b, c each with some coordinates (x, y), calculate the length of the segment opposite to each point (e.g. for a this is segment bc)
Order a, b, c by the length of their opposing segment in the order of [2nd longest, longest, shortest]
Return
Does this make sense? The real work is mapping to the euclidean distance between the opposing points. If you get stuck, update your question with your code and I'm happy to help you work it out.

Testing tetrahedron-triangle intersection

I want to determine whether a given triangle intersects a tetrahedron. I do not want to compute the solution polygon(if it exists) itself. Is there any library/package/published practical algorithm which can be used to solve this problem directly(unlike my attempt below)?
I think as a last resort I will have to use standard polygon-polygon intersection algorithm implementations to solve this problem indirectly.
My attempt on this problem:
I thought of breaking it into the problem of polygon-polygon intersection. So for each triangular face(say T1) of the tetrahedron and the given triangle T2, I thought of doing the following:
Compute intersection(a line) between planes corresponding to each triangle, say L1.
For each triangle:
For each edge of the triangle say L2, compute point of intersection P between L1 and L2.
Test(maybe using parametric form) of L2, if the point lies on the edge L2.
If for both triangles T1 and T2, there exists at least one edge on which the intersection point P lies, then it implies that the triangles(and hence the given tetrahedron and the triangle T2) do intersect.
Create an orthonormal frame based on the triangle (origin at some vertex, axis X using the direction of some side, axis Y and Z using the direction of another side and Gram-Schmidt formulas).
Transform the coordinates of the 3 + 4 vertices to the new frame.
If all Z of the 4 tetrahedron vertices are of the same sign, there is no intersection. Otherwise, find the 3 or 4 intersection point of the edges into XY, by linear interpolation on Z.
Now you need to check for intersections between a triangle and a triangle or (convex) quadrilateral, in 2D. You can solve that by means of a standard clipping algorithm, made simple by convexity of the polygons.
As an easy optimization, note that it is useless to compute the Z of the triangle vertices (=0), and the XY of the tetrahedron vertices before you know that there is a possible intersection.
You can also speedup the polygon intersection process by first using a bounding box test.
I just found a function in CGAL library CGAL::do_intersect(Type1< Kernel > obj1,Type2< Kernel > obj2 ) for computing intersection between two geometric objects. It permits Type1 and Type2 to be Triangle_3<Kernel> and Tetrahedron_3<Kernel> respectively.

Combine Arbitrary number of polygons together

I have an arbitrary number of polygons (hexes in this case) that are arranged randomly, but they are all touching another hex.
Each individual hex has 6 x,y vertices. The vertex's are known for all the hexes.
Can anyone point me in the direction of an algorithm that will combine all the hexes into a single polygon? Essentially I'm just looking for a function that spits out an array of vertex locations that are ordered in a way that when drawing lines from one to the next, it forms the polygon.
This is my method so far:
Create array of all the vertices for all the hexes.
Determine the number of times a vertex occurs in the array
If vertex is in the array 3+ times, delete the vertices from the array.
If vertex is in the array 2 times, delete one of them.
The next step is tricky though. I'm using canvas to draw out these polygons, which essentially involves drawing a line from one vertex to the next. So the order of the vertices in the final array is important. It can't be sorted arbitrarily.
Also, I'm not looking for a "convex hull" algorithm, as that would not draw the polygon correctly.
Are there any functions out there that do something like this? Am I on the right track or is there a better more efficient way?
I would do something like this:
List all the sides. A side is defined by two pairs of coordinates.
If any side shows up more than once remove all instances of that side.
Pick an arbitrary side, and from that side choose one of its points.
Place that point in an array.
Follow the current side and put the other point in the array.
Delete the side you just followed.
Then find the other side that has a point that is the same as the last point in the array. There will be only one such side. If there is none, you're done.
Go back to step 5.
You should now have an array of points that make up, in order, the shape you want.
Just be aware that this won't handle holes. The shape must be defineable by a single path.
without keeping track of the coordinate pairs that make up the lines, it would be impossible to determine the outer border of the shape
if you know the coordinate pairs that make up the lines, THEN
Create 2 lists, one of vertexs (list 1), one of the lines (list 2)
Remove all duplicate vertexes from the vertex list
Make a new list (list 3) of all the vertexes that have 3 lines attached to them
Using list 3, remove all the lines that have 2 vertexes from list 3 as their two coordinate pairs
It's time to traverse the shape, the list of lines remaining should form the shape you want
just start with an arbitrary coordinate and then
for each coordinate
for all lines
if (x1,y1) = current coordinate then add (x2,y2) to stack and remove that line from list
break
elseif (x2,y2) = current coordinate then add (x1,y1) to stack and remove that line from list
break
For each hex you have a list of 6 vertices. Sort the list, if necessary, so that the the vertices are ordered in counter-clockwise order (that's the mathematical convention).
Now you have a set of polygons (initially hexagons). The idea is to combine polygons until there is only one (or as few as can be).
Pick an edge of a polygon, and look for that same edge (i.e. that same pair of vertices) among the other polygons. If there are two instances, combine the two polygons at that edge, e.g. (a, b, c, d, e, f) + (g, h, d, c, i, j) => (a, b, c, i, j, g, h, d, e, f). (If the two vertices are in the same order in both polygons, or if there are three or more instances of the edge, report an error and abort.) Iterate through all edges. If the hexes really formed a contiguous group, there will be only one polygon left.
The polygon may have duplicated edges. If an edge occurs more than once, eliminate it by splitting the list in two, e.g. (a, b, c, d, b, a, e, f, g) => (b, c, d) + (a, e, f, g). Or if the the edges are adjacent, remove them: (a, b, c, b, d, e) => (a, b, d, e). Or if that list has only that edge, remove the list: (a,b) => nothing.
Once you've eliminated duplicate edges, there'll be one list for the counter-clockwise outer edge of the polygon, and perhaps one or more lists for the clockwise interior edges of holes.

Anyone know were i could find an algorithm or have a algorithm they could share to split a sphere (mesh) into random parts?

I have a list a vertices and a list of triangles. I'd like to split this single mesh into, say 5, randomly shaped meshes. When the 5 randomly shaped meshes are in place the sphere should all line up and look like 1 solid mesh.
I need a algorithm to do this programmatically, not a tool to do it form me. Any pointers would be great!
Similar to Svante's proposal but a slightly different approach:
Select five random vertices, mark these vertices as "visited" with the number 1 to 5
From each of the visited vertices, go to all adjacent vertices. Store the same number there as well.
If you visit a vertex which already has a number assigned, stop there
Stop, if all vertices are visited. All vertices marked with the same number end up in the same piece
This appears to me to be the simplest to implement, while still resulting in nice puzzle pieces. For added random-ness, you could add a probability, of visiting each adjacent vertex.
Nevertheless, any "too random" approach might result in heavily concave pieces, like very long pieces consisting only of a long strip of single triangles; and pieces with deep ugly thin cuts into them. You should possibly specify another question on how to make nice puzzle pieces (and what nice puzzle pieces are!) if you care for that.
You could make a crack by walking a random walk across the edges, until the number of pieces you want is achieved. If you want to have mostly big pieces, you could modify the randomness of the walk by reducing the attractiveness of edges that are close to an existing crack.
Select 3 random points and split along that plane. What is the problem?
When you split a triangle along a plane you end up in one of two situations: either the plane doesn't intersect either line segments in the triangle or it intersects exactly two line segments. Only triangles that are intersected are interesting.
If you have triangle (A, B, C), with A, B and C being vertices.
Assume that the plane intersects the line segments (A, B) and (A, C) in the points D and E.
Define a vertex, F, between B and C (for example B + (C - B) / 2), but any vertex on the line segment between B and C will do).
Your new triangles are then the following
(A, D, E), (B, D, F), (D, E, F) and (C, E, F)

Resources