I was using the Margin property of an Ellipse to define it’s offset from the borders.
This works as long as positive integral values are provided. Negative, non-integral values for margin values are technically permitted, but should be avoided because they are rounded by the layout rounding behavior.
This perfectly explains the behavior I was seeing where points would ‘lag behind’ a shape.
Again, thanks for you suggestions. It helped me verify the points where chosen correctly but just drawn incorrectly.
On to the EPA article :)
cheers!
Ernst
That’s a good suggestion and thanks for your offer. I’ll check if the points fall onto the sum shape. Maybe there is an error I can spot.
I’ll let you know!
thanks,
Ernst
The first thing I would check is if the distance check is working correctly minus the closest points in all quadrants. Then I would make sure that the Minkowski points are correct. The Minkowski points should be the points on the Minkowski sum that form the edge that is closest to the origin (see Figure 6).
If you still can’t find the problem you are welcome to send me the code via or by posting it here.
William
]]>First of all, thanks for the great articles you’ve put online!
I’ve been playing with an implementation in C#/WPF based on this text and the dyn4j code. Everything looks quite alright but there is an small issue with the closest point that you might be able to give me some hints on.
I have the following (default) quadrant setup;
4 | 1
——–
3 | 2
the origin (0,0) is in the middle of my screen. q1 = x > 0 && y > 0; q2 = x > 0 && y < 0 and so on.
The results look fine whenever I keep both polygons inside the first quadrant. i.e. all the vertices have a positive value. As soon as I move one or more shapes to a different region the closest points start to drift. Is this something you've seen before using this algorithm or am I overlooking a minus sign somewhere and just need to look harder?
Thanks!
Ernst
b.t.w. I'm in 2d as you might have guessed.
]]>For the 3D case you can build a triangle (after building the line segment) by obtaining a normal of the line segment in the direction of the origin:
d = // choose some direction // get the first point Simplex.add(support(A, B, d); // get the second point Simplex.add(support(A, B -d); // now we have a line segment // perform the triple product to obtain a new search direction a = Simplex[0]; b = Simplex[1]; ab = b - a; ao = -a; // same thing as ORIGIN - a d = tripleProduct(ab, ao, ab); // be careful here because if the origin lies on the line ab then this will yield the zero vector // now get the last point to make the triangle Simplex.add(support(A, B, d); // now you can start the loop
Now that you have a triangle your next search direction would be the surface normal of the triangle in the direction of the origin. Then obtain a support point, then reduce the 4 points to 3.
]]>One more question, I’m trying to do a 3D case. So I need to build a triangle first then add a point in the search direction to get a tetrahedron. How to get the first triangle? With the same method in 2D, I can easily find a line segment, then doing a triple cross product will give a third point and thus generating a triangle. Do you think this can be the triangle to start with? thanks.
]]>As for question 1: You do not have to check if the simplex contains the origin. The simplex in the distance check is a line segment anyway and can only “contain” the origin if the origin lies on the line segment, in which case you must determine if this is considered a collision or not. You may have noticed that in my code I do check if the origin lies within the triangle (before throwing away one of the points). I do this because my distance method can be called by anyone, and they may not know that the distance method assumes that the shapes are separated. Otherwise I would remove that check.
As for question 2: Right, the termination case is a bit tricky. You know to terminate the loop when the new point you found via the support function is projected onto the search direction and that projection is not greater than zero.
So in iteration 1, you find c, the new point, to be (-11, -1). If we project this onto the search direction:
d.dot(-11, -1) = -0.32 * -11 + -0.95 * -1 = 4.47
It’s greater than zero so that means that we were able to move the simplex in the given direction.
So in iteration 2, you find c to be (-4, -1). If we project this onto the search direction:
d.dot(-4, -1) = 0.32 * -4 + -0.95 * -1 = 0.15
It’s greater than zero so that means that we were able to move the simplex in the given direction.
Now in iteration 3, you find c to be (1, 3) or (-4, -1). If we project this onto the search direction:
d.dot(1, 3) = 0.62 * 1 + -0.78 * 3 = -1.72 or
d.dot(-4, -1) = 0.62 * -4 + -0.78 * -1 = -1.7
Here we see that the projection of the point(s) is less than zero, this means that we cannot get any closer to the origin.
]]>Finding the distance is similar but slightly different. No longer are we checking if the simplex contains the origin since the assumption is that the Minkowski sum does not contain the origin. In addition, the simplex is a line segment, instead of a triangle, and therefore cannot contain the origin (if we ignore cases where the origin is on the line segment). Because of this we don’t need to worry about voronoi regions or where the origin lies. The search direction is always the normal of the line segment in the direction of the origin.
Given that, I chose to use P = AB.mult(t).add(A) which obtains the point on the line segment that is closest to the origin so that when the loop terminates I’ll be able to get the separation distance by simply getting the magnitude of P.
]]>So (-11,-1) is added on as the new point A, same as in your post. Then I do the triple cross product to find the direction (0.316, -0.949) to search. doing dot product of all vertices with the new searching direction gives all negative values. So, question 2, does it mean the loop should be terminated here? or should I keep on searching in another direction until it leads back to the vertex that has already been checked before? Cuz when I keep on doing triple cross product to find the new point, it leads me to (-4,-1), and then back to (1,3) where I started.
Thanks a lot for answering all my questions.
]]>