I'm implementing the Expanding Polytope Algorithm, and I am unsure how to deduce the contact points from a point on the minkowski difference - algorithm

I've been reading about the EPA from several sources, but they all seem to abruptly stop being useful after the closest point on the minkowski difference to the origin is located. Most of them say something along the lines of "With this information, we can then generate the local and global contact points and contact tangents," but I don't understand how that is even possible, much less how to do it. I don't see how someone could derive the minuend and subtrahend from a difference alone, and certainly not in a reasonable amount of time. What is the standard solution to this problem?
I am looking to implement this algorithm in 3D, if that changes the answer. Thanks

OP of the blog post here.
The post actually says how to compute the contact point in step 8 of the EPA algorithm:
Project the origin onto the closest triangle. This is our closest
point to the origin on the CSO’s boundary. Compute the barycentric
coordinates of this closest point with respect to the vertices from
the closest triangle. The barycentric coordinates are coefficients of
linear combination of vertices from the closest triangle. Linearly
combining the individual support points (original results from
individual colliders) corresponding to the vertices from the closest
triangle, with the same barycentric coordinates as coefficients, gives
us contact points on both colliders in their own model space. We can
then convert these contact points to world space.
Allow me to rephrase it here.
Let Ca, Cb, and Cc denote the three vertices of the triangle of the CSO that contains the closest point, denoted Cp, on the CSO boundary to the origin.
Compute the barycentric coordinate (x, y, z) of the triangle for Cp.
x Ca + y Cb + z Cc = Cp
Note that it is required that we keep the original support function results in global space from the two objects (A & B) used to obtain Ca, Cb, and Cc. Let Aa, Ab, and Ac denote the original support function results for object A. Let Ba, Bb, and Bc denote the original support function results for object B.
Ca = Aa + Ba
Cb = Ab + Bb
Cc = Ac + Bc
Using the barycentric coordinate (x, y, z) obtained earlier to linearly combine the original support function results from object A & B, we can compute the contact points on both objects, denoted Ap and Bp:
Ap = x Aa + y Ab + z Ac
Bp = x Ba + y Bb + z Bc
I hope this clarifies the computation process for you.

Related

How can I find the coordinates of the resulting vector so that I can display it on an image?

I try to calculate and display a point on an image. Suppose I have the following points:
A = (x1, y1)
B = (x2, y2)
C = (x3, y3)
I want to calculate the coordinates of the resulting vector between the vectors AB and AC. What I thought:
AB=(x2-x1,y2-y1)
AC=(x3-x1,y3-y1)
and the resulting vector would be
AD(for example)=(((x2-x1)+(x3-x1)),((y2-y1)+(y3-y1)))
I'm not sure I thought well mathematically, but my biggest problem is that the result does not match the image, the coordinates can give negative numbers after this calculation. How can I find the coordinates of the resulting vector so that I can display it on an image?
I also added a small image, to better understand what I'm trying to say:
What you are doing is essentially adding two vectors, AD = AC + AB. So your image is correct if that is what you want to do. As for the negative numbers this depends on what your vectors are. The vector will be negative if it goes opposite the positive directions of your coordinate system.
Added an image to show how the vector AD is made graphically:
I recommend checking out some basic vector operations
EDIT: found similar topics:
How to get the vector between two vectors?
Hmm so if I see it right you want something between mirror and projection ... As there is probably no guarantee than AB and AC are symmetrical ...
I would try this using vector math:
ba = A-B
bc = C-B
E = B + bc* dot(ba,bc)/(|bc|^2)
D = E + (E-A)
D = 2.0*E - A
D = 2.0*(B + bc* dot(ba,bc)/(|bc|^2)) - A
Where dot(a,b)=a.x*b.x+a.y*b.y is scalar multiplication and |a|^2=(a.x*a.x)+(a.y*a.y) is vector size squared
So the E is perpendicular projection of A onto BC and D is mirror reflection of A around E and BC ...

How to get Voronoi site points from a diagram

Say we have got a Voronoi diagram from somewhere but there are no points.
Like this but without red points:
We have only borders.
Is there any algorithm that can help to retrieve the points?
And what if we have unlimited Voronoi diagram that is stretching long way. Can we have at least one point calculated or are there any heuristic algorithms?
For a single intersection of the Voronoi diagram, you will generally have 3 edges, and 3 sectors between the edges. Call the sectors (and their angles) A, B, and C. Also, call the edge between sectors A and B the edge ab, and likewise for edges bc and ca.
There should be an original site point within each of these sectors; let site a be the site in sector A, site b in sector B, and site c in sector C.
Note that the angles to the sites on either side of a sector boundary must be equal, because the distance from the Voronoi edge to each site must be equal. For example, the angle from site a to edge ab must be the same as the angle from edge ab to site b; call this angle X. Likewise let angle Y be the angle from site b to edge bc and from bc to site c; and Z the angle from c to ca and from ca to a.
This gives you the equations:
A = Z + X
B = X + Y
C = Y + Z
With the solution (simplified because A + B + C == 2 * pi):
X = (A + B - C)/2 = pi - C
Y = (B + C - A)/2 = pi - A
Z = (C + A - B)/2 = pi - B
This gives you a ray from any Voronoi intersection to each of its 3 sites. And the intersection of the rays from neighboring Voronoi intersections to the same cell site will give you a location for that site.
And, to answer your second question: if you only have 3 sites, then you can only have one Voronoi intersection. In that case, you won't be able to determine your sites -- just their angles from the intersection.
In all other general cases, you can find at least one site as described above; reflection across Voronoi edges should then determine the location of all other sites, including extremal cells that have only one Voronoi intersection.
This question was investigated and half-solved by Ash and Bolker in 1985. For
a more modern version that completes that early work, see this:
Biedl, Therese, Martin Held, and Stefan Huber. "Recognizing straight skeletons and Voronoi diagrams and reconstructing their input." In Voronoi Diagrams in Science and Engineering (ISVD), 2013 10th International Symposium on, pp. 37-46. IEEE, 2013.
(IEEE link.)
(Image from Stefan Huber.)

place points with only distance matrix

I want to visualize some points, but only a distance matrix for them is given. It is there any good method to get one possible way to place them on 2D space.
Input: a distance matrix
Ouput: coordinates of these points
For a given matrix, if you come up with a possible placement, then any translation of the points will also satisfy the matrix, as will any rotation, and also mirroring.
For one possible placement:
Choose 3 points A B C (i.e. 3 rows from the matrix) that form a triangle with distances AB, AC and BC taken from the matrix. The points can't all lie on a line, so AB != AC + BC, AC != AB + BC and BC != AB + AC.
Place A at the origin and B at (AB, 0). Then use the Cosine rule to deduce the angle between the lines AB and AC:
angle = arccos((AB2 + AC2 - BC2) / (2 * AB * AC))
Now that you have the angle you can calculate the position of C:
C = (cos(angle) * AC, sin(angle) * AC);
You now have positions for A B and C. You can go through each of the other rows in the matrix corresponding to the other points, and find the distance between each point and A B and C. Then you can use this formula to work out the position of the point based on your assumed positions of A B C and the distance of the point to each:
Finding location of a point on 2D plane, given the distances to three other know points
So, you only actually need 3 values from each row of the matrix. For a large matrix, most of it is totally redundant. This might be helpful to you if you are trying to minimize storage space.
Remember that any translation, rotation and mirroring is also valid.

How to do Ray and Triangle Edge intersect?

I'm facing problem intersecting ray with triangle edges. Actually, I'm trying to pick/intersect with triangle, vertex, edge of a mesh using Mouse. So I made ray from the Mouse current position and then I intersect it with the mesh elements like triangle/polygon, vertex, edge etc to work with it. Basically, 3d modeling stuffs. Intersecting with triangle was easy and fun. And the vertex part was tricky.
But now, I don't know how to intersect/pick with triangle edges. I mean how I treat them when intersecting with the Mouse Ray? First I thought they can be treated like a 3D line. But eventually failed to do the Ray and the Line intersect. Searched on the Internet but not found any helpful info. Although I found some open source projects are using OpenGL built-in picking features to pick/intersect with Edge. But in my case, I can't use that. :(
My current edge picking code structure looks like the following:
void pickEdge(Ray ray, Scene scene)
{
for each object in scene
{
mesh = getMesh(object)
for each triangle in mesh
{
for each edge in triangle
{
v1 = getV1(edge)
v2 = getV2(edge)
// Do intersect with 'ray' and 'v1', 'v2'. But how?
}
}
}
}
So I'm stuck here and really need some help. Any idea, algorithm or a small help is greatly appreciated.
In your case problem of finding intersection between triangle and ray in 3D space can be boiled down to finding point location (INSIDE, OUTSIDE, ON BOUNDARY) in triangle in 2D space (plane). All you should do is project triangle on screen plane, find intersection on edge and perform reverse projection on edge. Position of point is position of mouse. The only problem is to treat degenerate cases like mapping triangle into line segment. But I think it will not be problem, because such cases can be easily coped.
Please give a look to the algorithms at the end of this page and more in general all the ones that this website offers: http://geomalgorithms.com/a05-_intersect-1.html
The first approach is to orthogonally project the edge (and the ray) to a plane perpendicular to the ray, and then to compute the distance of the projected ray to the projected edge.
Ie., first you determine two orthogonal vectors rdir1, rdir2 orthogonal to your ray.
Then you calculate the projection of your ray (its base point) to this plane, which will simply yield a 2d point rp.
Then you project the edge to that plane, by simply applying dot products:
pv1 = new Vector2(DotProduct(v1, rdir1), DotProduct(v1, rdir2))
pv2 = new Vector2(DotProduct(v2, rdir1), DotProduct(v2, rdir2))
Now you can compute the distance from this 2d line pv1, pv2 to the point rp.
Provided that the direction of the edge is taken from the view matrix's "forward" direction, then two vectors orthogonal to that would be the view matrix's left and right vectors.
Doing the above recipe will then yield something similar to projecting the edge to the screen. Hence, alternatively you could project the edge to the screen and work with those coordinates.
First of all, what is the distance between two geometric objects A and B ? It is the minimal distance between any two points on A and B, ie. dist(A,B) = min { EuclideanLength(x - y) | x in A, y in B}. (If it exists and is unique, which it does in your case.)
Here EuclideanLength((x,y,z)) = sqrt(x^2 + y^2 + z^2) as you already know. Because sqrt is strictly increasing it suffices to minimize SquareEuclideanLength((x,y,z)) = x^2 + y^2 + z^2, which greatly simplifies the problem.
In your question the objects are a line segment A := {v1 + t*(v2-v1) | 0 <= t <= 1} and a line B := {p + s*d | s is any real number}. (Don't worry that you asked about a ray, a line is really what you want.)
Now calculating the distance comes down to finding appropriate t and s such that SquareEuclideanLength(v1 + t*(v2-v1) - p - s*d) is minimal and then computing EuclideanLength(v1 + t*(v2-v1) - p - s*d) to get the real distance.
To solve this we need some analytic geometry. Because d is not zero, we can write each vector v as a sum of a part that is orthogonal to d and a part that is a multiple of d: v = Ov + Mv. For such an "orthogonal decomposition" it always holds SquareEuclideanLength(v) = SquareEuclideanLength(Ov) + SquareEuclideanLength(Mv).
Because of d = Md in the above
SquareEuclideanLength(v1 + t*(v2-v1) - p - s*d) =
SquareEuclideanLength(Ov1 + t*(Ov2-Ov1) - Op)
+ SquareEuclideanLength(Mv1 + t*(Mv2-Mv1) - Mp - s*d)
the left addend does not depend on s and however you chose t you can find an s such that the right addend is 0 ! (Remember that Mv1, Mv2, ... are multiples of d.)
Hence to find the minimum you just have to find such maps O, M as above and find the minimizer t.
Assuming that d is normalized, these are actually given by Ov := CrossProduct(v, d) and Mv := DotProduct(v, d)*d, but just believe me, that this also works if d is not normalized.
So the recipe for finding the distance is now: find 0 <= t <= 1 that minimizes
SquareEuclideanLength(Cross(v1 - p, d) + t*Cross(v2 - v1, d))
= SquareEuclideanLength(Cross(v1 - p, d))
+ 2*t*Dot(Cross(v1 - p, d), Cross(v2 - v1, d))
+ t^2 SquareEuclideanLength(Cross(v2 - v1, d)).
You will already know this formula from Point-Line distance calculation (that's what it is) and it is solved by differentiating with respect to t and equalling 0.
So the minimizer of this equation is
t = -Dot(Cross(v1 - p, d), Cross(v2 - v1, d))/SquareEuclideanLength(Cross(v2 - v1, d))
Using this t you calculate v1 + t*(v2 - v1), the point on the line segment A that is closest to line B and you can plug this into your point-line distance algorithm to find the sought after distance.
I hope this helps you !

Position of connected points in space

A-B-C-D are 4 points. We define r = length(B-C), angle, ang1 = (A-B-C) and angle ang2 = (B-C-D) and the torsion angle tors1 = (A-B-C-D). What I really need to do is to find the coordinates of C and D provided that I have the new values of r, ang1, ang2 and tors1.
The thing is that the points A and B are rigidly connected to each other, and points C and D are also connected to each other by a rigid connector, so to speak. That is the distance (C-D) remains fixed and also distance A-B remains fixed. There is no such rigid connection between the points B and C.
We have the old coordinates of the 4 points for some other set of (r,ang1,ang2,tors1) and we need to find the new coordinates when this defining set of variables changes to some arbitrary value.
I would be grateful for any helpful comments.
Thanks a lot.
I'm not allowed to post a picture because I'm a new user :(
Additional Info: An iterative solution is not going to be useful because I need to do this in a simulation "plenty of times O(10^6)".
I think the best way to approach this problem would be to think in terms of analytic geometry.
Each point A,B,C,D has some 3D coordinates (x,y,z) and you have some relationships between
them (e.g. distance B-C is equal to r means that
r = sqrt[ (x_b - x_c)^2 + (y_b - y_c)^2 + (z_b - z_c)^2 ]
Once you define such relations it remains to solve the resulting system of equations for the unknown values of coordinates of the points you need to determine.
This is a general approach, if you describe the problem better (maybe a picture?) it might be easy to find some efficient ways of solving such systems because of some special properties your problem has.
You haven't mentioned the coordinate system. Even if (r, a1, a2, t) don't change, the "coordinates" will change if the whole structure can be sent whirling off into space. So I'll make some assumptions:
Put B at the origin, C on the positive X axis and A in the XY plane with y&gt0. If you don't know the distance AB, calculate it from the old coordinates. Likewise CD.
A: (-AB cos(a1), AB sin(a1), 0)
B: (0, 0, 0)
C: (r, 0, 0)
D: (r + CD cos(a2), CD sin(a2) cos(t), CD sin(a2) sin(t))
(Just watch out for sign conventions in the angles.)
you are describing a set of constraints.
what you need to do is for every constraint check if they are still satisfied, and if not calc the most efficient way to get it correct again.
for instance, in case of length b-c=r if b-c is not r anymore, make it r again by moving both b and c to or from eachother so that the constraint is met again.
for every constraint one by one do this.
Then repeat a few times until the system has stabilized again (e.g. all constraints are met).
that's it
You are asking for a solution to a nonlinear system of equations. For the mathematically inclined, I will write out the constraint equations:
Suppose you have positions of points A,B,C,D. We define vectors AB=A-B, etc., and furthermore, we use the notation nAB to denote the normalized vector AB/|AB|. With this notation, we have:
AB.AB = fixed
CD.CD = fixed
CB.CB = r*r
nAB.nCB = cos(ang1)
nDC.nBC = cos(ang2)
Let E = D - DC.(nCB x nAB) // projection of D onto plane defined by ABC
nEC.nDC = cos(tors1)
nEC x nDC = sin(tors1) // not sure if your torsion angle is signed (if not, delete this)
where the dot (.) denotes dot product, and cross (x) denotes cross product.
Each point is defined by 3 coordinates, so there are 12 unknowns, and 6 constraint equations, leaving 6 degrees of freedom that are unconstrained. These are the 6 gauge DOFs from the translational and rotational invariance of the space.
Assuming you have old point positions A', B', C', and D', and you want to find a new solution which is "closest" (in a sense I defined) to those old positions, then you are solving an optimization problem:
minimize: AA'.AA' + BB'.BB' + CC'.CC' + DD'.DD'
subject to the 4-5 constraints above.
This optimization problem has no nice properties so you will want to use something like Conjugate Gradient descent to find a locally optimal solution with the starting guess being the old point positions. That is an iterative solution, which you said is unacceptable, but there is no direct solution unless you clarify your problem.
If this sounds good to you, I can elaborate on the nitty gritty of performing the numerical optimization.
This is a different solution than the one I gave already. Here I assume that the positions of A and B are not allowed to change (i.e. positions of A and B are constants), similar to Beta's solution. Note that there are still an infinite number of solutions, since we can rotate the structure around the axis defined by A-B and all your constraints are still satisfied.
Let the coordinates of A be A[0], A[1] and A[2], and similarly for B. You want explicit equations for C and D, as you mentioned in the response to Beta's solution, so here they are:
First find the position of C. As mentioned before, there are an infinite number of possibilities, so I will pick a good one for you.
Vector AB = A-B
Normalize(AB)
int best_i = 0;
for i = 1 to 2
if AB[i] < AB[best_i]
best_i = i
// best_i contains dimension in which AB is smallest
Vector N = Cross(AB, unit_vec[best_i]) // A good normal vector to AB
Normalize(N)
Vector T = Cross(N, AB) // AB, N, and T form an orthonormal frame
Normalize(T) // redundant, but just in case
C = B + r*AB*cos(ang1) + r*N*sin(ang1)
// Assume s is the known, fixed distance between C and D
// Update the frame
Vector BC = B-C, Normalize(BC)
N = Cross(BC, T), Normalize(N)
D = C + s*cos(tors1)*BC*cos(ang2) + s*cos(tors1)*N*sin(ang1) +/- s*sin(tors1)*T
That last plus or minus depends on how you define the orthonormal frame. Try one and see if it's what you want, otherwise it's the other sign. The notation above is pretty informal, but it gives a definite recipe for how to generate C and D from A, B, and your parameters. It also chooses a good C (which depends on a good, nondegenerate N). unit_vec[i] refers to the vector of all zeros, except for a 1 at index i. As usual, I have not tested the pseudocode above :)

Resources