Finding point of collision (moving circles + time) - math

For two circles moving linearly, it's easy enough to calculate the time of the collision: http://twobitcoder.blogspot.com/2010/04/circle-collision-detection.html
This assumes that the circles have fixed starting points, and fixed movement paths, and calculates the time of the collision.
Is it possible to do it the other way around:
Circle 1: Starting point X1,Y1 velocity VX1,VY1 (fixed starting point, fixed linear movement path), radius R1
Circle 2: Starting point X2,Y2 velocity scalar (1m/sec, etc) (fixed starting point, fixed speed, unknown direction), radius R2
Is it possible to determine the collision position of the two circles for a minimum travel time?
I.E.
Circle 1 starts at 0,0 and moves at speed 1,0 (1 unit to the right per time)
Circle 2 starts at 5,5 and can move 1 unit per time
What would the collision position be (or the VX2,VY2 circle 2 would need to move in) in order for the 2 circles to collide at the lowest time T.
Radius of both circles is 1
In this example, a solution would be somewhere around Circle 1 being at point 3,0 at time 3. The question feels fairly complex as you have unknown variables: collision point, collision time, VX2, VY2. Although VX2 and VY2 would be constrained by |VX1|+|VX2| = 1.
The reason for the question is to tell circle 2 where it should move to in order to 'catch' circle 1.
The brute force solution would be to check the position of circle 1 at every time interval, and calculate if circle 2 would collide with circle 1 if told to move to that point - but you could miss collision points of the circles were moving fast, or get a sub-optimal point, etc.

There are two keys to solving this simply:
Firstly the points reachable from x2 in time t form a circle centered on x2.
Secondly the first moment that the circles can touch they must be touching tangentially.
These combine to tell us that the points x2(0), x2(T), the contact point and x1(T) are all colinear.
If we draw a diagram showing this we get a single quadratic equation in t:
|| x2(0) - x1(0) - v1 t ||^2 = (r1+r2+t)^2
Which can easily be solved for t.
To get the direction for v2 we just need to use the unit vector in the direction x1(T)-x2(0).

Related

Determine whether a point is on the left or right of a line in 3D [duplicate]

I am currently trying to write a shader in unity that draws a triangular pattern around countries in a risk-styled game if both countries are not owned by the same player (visual aid to see your borders).
Right now, I'm having an issue with making the shader set the countries properly.
It always sets country 0 to the left, and country 1 to the right - country 0 and 1 are set programically.
The line, a border, can be between 0 and 359 degrees.
How I find the countries 0 and 1 is I draw 3 points to the left and right of the midpoint of the line, one .01f, one .1f and one 1f away from the midpoints in each direction, then spin them around the midpoint to the appropriate location.
After that I do an even-odd check to see if the points are inside or outside of each country, and compare the weight results (closest gets 3 points, mid gets 2, furthest gets 1, just in case someone builds a really screwed up country that flanks the other country).
In my test map, a close to equally sliced octagon, the borders showed up correctly (after I reversed the positions of country 0 and 1 in the event the angle was over 90 and less then or equal 180). Worked without a flaw, but in other maps it doesn't work very well.
Everything but the country allocation works well, so I'm curious if anyone knows of a better way to figure out which point is to the left or a spun line, or a better conceptual way to handle this.
That above is basically when I'm doing, red being left right being blue, then I'm just checking 3 different spots then weighing in the lefts and rights found with even/odding it into the appropriate countries (one at +/- .01, the other at +/- .1 and the third 1, in case of even/odd rounding issues with closeness).
I then flip them if I find that country A is to the right, as it is on the left according to the angles I had draw. (my shader renders left first and right second, hence why I do this).
which way is left/right on a line?
From last edit is this not your case. Why not use dot product?
So if the line goes in -x direction the result is negative and if in the +x direction then the result is positive. if the result is zero that means the line goes up or down only or it is juts a point. If you need specific direction instead of left/right then use appropriate a vector instead of x axis.
dot(a,b)=a.x*b.x+a.y*b.y in 2D
dot(a,b)=a.x*b.x+a.y*b.y+a.z*b.z in 3D
Image is relevant for cases where a vector is in unit size in that case the result of dot is perpendicular projection of b into a just like on image
on which side is some point?
I think this is what you need.
As you can see if you handle line (P0,P1) and point P you want to classify as triangle then its polygon winding determines also the side of the line. So for implicit axis directions:
CW(clockwise) polygon winding means right side of the line
CCW(counter-clockwise) polygon winding means left side of the line
How to get winding? ... simply compute normal vector and get its Z coordinate. Its polarity (sign) determines winding (CW/CCW or the other way around depends on the coordinate system).
normal vector is computed as cross product of the two vertices of triangle (P1-P0)x(P-P1)
No need to compute other axises just the z so:
normal.z = ((P1.x-P0.x)*(P.y-P1.y)) - ((P1.y-P0.y)*(P.x-P1.x))
Now just do if (normal.z<0) ... else ... it should never be zero unless you call it for point on the line or the line is a point ... look here at similar question: Determine rotation direction /toward/ variable point on a circle

Weird phenomenon with three.js plane

This is the first question I've ever asked on here! Apologies in advance if I've done it wrong somehow.
I have written a program which stacks up spheres in three.js.
Each sphere starts with randomly generated (within certain bounds) x and z co-ordinates, and a y co-ordinate high above the ground plane. I casts rays from each of the sphere's vertices to see how far down it can fall before it intersects with an existing mesh.
For each sphere, I test it in 80 different random xz positions, see where it can fall the furthest, and then 'drop' it into that position.
This is intended to create bubble towers like this one:
However, I have noticed that when I make the bubble radius very small and the base dimensions of the tower large, this happens:
If I turn the recursions down from 80, this effect is less apparent. For some reason, three.js seems to think that the spheres can fall further at the corners of the base square. The origin is exactly at the center of the base square - perhaps this is relevant.
When I console log all the fall-distances I'm receiving from the raycaster, they are indeed larger the further away you get from the center of the square... but only at the 11th or 12th decimal place.
This is not so much a problem I am trying to solve (I could just round fall distances to the nearest 10th decimal place before I pick the largest one), but something I am very curious about. Does anyone know why this is happening? Has anybody come across something similar to this before?
EDIT:
I edited my code to shift everything so that the origin is no longer at the center of the base square:
So am I correct in thinking... this phenomenon is something to do with distance from the origin, rather than anything relating to the surface onto which the balls are falling?
Indeed, the pattern you are seeing is exactly because the corners and edges of the bottom of your tower are furthest from the origin where you are dropping the balls. You are creating a right triangle (see image below) in which the vertical "leg" is the line from the origin from which you are dropping the balls down to the point directly below on mesh floor (at a right angle to the floor - thus the name, right triangle). The hypotenuse is always the longest leg of a right triangle, and the futher out your rays cast from the point just below the origin, the longer the hypotenuse will be, and the more your algorithm will favor that longer distance (no matter how fractional).
Increasing the size of the tower base would exaggerate this effect as the hypotenuse measurements can now grow even larger. Reducing the size of the balls would also favor the pattern you are seeing, as now each ball is not taking up as much space, and so the distant measurments to the corners won't fill in as quickly as they would with larger balls so that now more balls will congregate at the edges before filling in the rest of the space.
Moving your dropping origin to one side or another creates longer distances (hypotenuses) to the opposites sides and corners, so that the balls will fill in those distant locations first.
The reason you see less of an effect when you reduce the sample size from 80 to say, 20, is that there are simply fewer chances to detect these more distant locations to which the balls could fall (an odds game).
A right triangle:
A back-of-the-napkin sketch:

How to find the appropriate rotation of a pentagon for fitting into a LibGDX hex-tessellated sphere?

I've got a tricky question today which involves a lot of vectors. I'm trying to keep them all straight. What I have is this shape (mostly hexagons with 12 pentagons): http://i.imgur.com/WDSWEcF.jpg
And I want to place 12 pentagon meshes into their 12 spots. I start by creating the 12 meshes at the origin (the center of this shape) and then using the following code to rotate and move them into position.
for (int i = 0; i < 12; ++i) {
Vector3 pentPoint = pentPoints.get(i); // The center of each pentagon.
ModelInstance pent = pents.get(i);
Vector3 direction = (pentPoint).cpy().sub(new Vector3(0, 0, 0))
.nor();
direction.set(direction.x, direction.y, direction.z);
pent.transform.setToRotation(Vector3.Y, direction);
pent.transform.setTranslation(pentPoint);}
Now, this is almost what I need. It results in this: http://i.imgur.com/Ch5Jhb8.jpg. Forgetting about the scaling for now, you can see that the pentagon is rotated improperly. It doesn't line up with its slot. I know that I can fix this rotation using pent.transform.rotate(Vector3.Y, *value*); based on some value for each pentagon. The problem is, I have no idea how I can calculate what this value should be.
Can anyone help or point me to some resources? Alternatively, I could use the fact that I know the coordinate of every vertex in the shape to fill in these pentagons by drawing triangles using LibGDX's ModelBuilder. I think this would be less performant than positioning the .objs. Thoughts?
I don't know anything about the library you're using, but maybe I can help with the geometry. One approach would be to draw a mesh for 1/5 of one of the pentagons. I suggest you do that in place, rather than at the origin. You need to know two adjacent vertices of a pentagon. From that, you can easily calculate the center of the pentagon (I can supply formulas if you wish). The three points you now have determine a triangle which is a "fundamental domain" for the rotation group of the dodecahedron. If you have a mesh on the fundamental domain, it can be propagated to the other 4/5 of the pentagon you chose by repeating a 72 degree rotation about the axis through the origin determined by the center of the pentagon. Call that rotation A. You can represent it by axis angle, quaternion, whatever.
To propagate the mesh to other pentagons in the figure, you just need one more rotation: a 180 degree rotation which takes your chosen pentagon to another nearby pentagon. Again, I could give a formula for the axis if you like, but if you can find the center of a second pentagon with the information you already have, the axis is determined by the midpoint of the segment connecting the two centers. (You may have to normalize the point determining the axis, depending on how you represent rotations.) Call the 180 degree rotation about that axis rotation B.
Rotation A and B together generate the entire 60 element rotation group of the icosahedron, which will allow you to propagate the mesh on the fundamental domain to every other pentagon in the figure. If you're not careful, however, you may hit some parts twice and others not at all. I think you can do it in this order: start with a fundamental domain. 4 A's fill in the first pentagonal face (let's call it the north pole). Then a B will map that pentagon to an adjacent pentagon. 4 more A's will fill in a meridian of pentagons. Another B will take a pentagon on the meridian to the other meridian. 4 more A's will fill in the second meridian. Finally another B will map a pentagon on the second meridian to the south pole.
The orientations of all the pentagons will be correct in this procedure.
Does that help?

How to repositionate a bouncing ball after it passed throug a surface

I have a bouncing ball which can collide lines with random slope. The ball pass through the lines of a bit and i need to set back the ball at a "radius" distance from the line.
Ball (with variables x, y and radius) travels at speedX and speedY (obtained from vectors directionX and directionY multiplied for a variable) and i can know the distance (dist) between the center and the line so i can know how many pixels the ball passed through the line
Think that in the example the ball passed 10 pixels (radius - dist) after the line, i need to set back the center of the ball 10 pixels in the opposite vector (directionX directionY). My question is:
How can i calculate how to split those n pixels between x and y so i can subtract them from the center coordinates?
I can imagine 4 different resolutions of what you have, and it is unclear which one you want.
Here they are, where the black arrow is the movement of the centre of the ball between the frame before collision and the frame you are asking how to draw.
A) the situation which you have now.
pro : simple
con : ball is in a physically unacceptable position
B) you compute where the ball should be after having bounced (assuming an elastic chock)
pro : most accurate
con : you don't have a frame with the ball in contact with the surface (but do you care ?).
C) The position of the ball is A, brought back to being tangent at the surface, with a correction that is orthogonal to said surface
pro : conserves accuracy in direction parallel to surface
con : centre of the ball not on the reflected line (i.e. we take liberties with Descartes' law)
D) The ball is still on the incoming line, but stopped when it is tangent to the surface.
pro : only the speed/timing is messed with
con : err.... out of ideas here. Still not as precise as B.
Well, disregarding all the drawings, it is much easier to take only the centre of the ball, and consider it hits a line that is at 'radius' of the real surface (and parallel to it), so we only have mechanics for a single point. Thus from the previous image, we get the formulation in terms of the following red objects :
So what do we need to do all this ?
The undisturbed trajectory starts at point S, ends at point E (the endpoint of situation A). We will call C the collision point between both lines (red one and trajectory, thus the endpoint of trajectory D).
I will assume we are always in the case of a collision, thus the point of intersection C between the undisturbed trajectory and the surface always exists.
You will also need the vector u that is perpendicular to the surface. Be sure to take a unit vector that points towards the side where the ball is. Thus if your slope has an equation ax+by+c=0, start with the vector ( a/sqrt(a*a+b*b) , b/sqrt(a*a+b*b) ) and multiply both coordinates by -1 if it points to the wrong side.
Then, to shift the line by a distance r in the direction of u, you want the equation a(x-r*u.x)+b(y-r*u.y)+c=0 thus ax+by+c-r*(a*u.x+b*u.y)=0
So if r is the radius and ax+by+c=0 your surface, the red line's equation is ax+by+c+r*sqrt(a*a+b*b)=0
or -r if the ball is beneath the line.
I will write PQ the vector starting at point P and ending at point Q, thus coordinates of said vector will be (Q.x - P.x, Q.y - P.y) and a . between two vectors will mean a scalar product.
So you can express SE in terms of the variables you named directionX, directionY and dist.
A) Move center by SE. Yay, finished !
B) Get C. Move center by SE - 2 * (CE . u) * u : thus the total move, but removing twice the normal component of CE that goes beyond the surface, effectively mirroring the CE vector by that surface.
C) Get C. Move center by SE - (CE . u) * u : the same, but remove the normal component of CE only once, effectively projecting the CE vector on the red line.
D) Get C. Move center by SC.

Closest Approach question for math/physics heads

I'm using a Segment to Segment closest approach method which will output the closest distance between two segments of length. Each segment corresponds to a sphere object's origin and destination. The speed is simply from one point, to the other.
Closest Approach can succeed even when there won't be a real collision. So, I'm currently using a 10-step method and calculating the distance between 2 spheres as they move along the two segments. So, basically the length of each segment is the object's traverse in the physics step, and the radius is the objects radius. By stepping, I can tell where they collide, and if they collide (Sort of; for the MOST part.)..
I get the feeling that there could be something better. While I sort of believe that the first closest approach call is required, I think that the method immediately following it is a TAD weak. Can anyone help me out? I can illustrate this if needed.
Thanks alot!
(source: yfrog.com)
(I don't know how to post graphics; bear with me.)
All right, we have two spheres with radii r1 and r2, starting at locations X1 and X2, moving with velocities V1 and V2 (X's and V's are vectors).
The velocity of sphere 1 as seen from sphere 2 is
V = V1-V2
and its direction is
v = V/|V|
The distance sphere 1 must travel (in the frame of sphere 2) to closest approach is
s = Xv
And if X is the initial separation, then the distance of closest approach is
h = |X - Xv|
This is where graphics would help. If h > r1+r2, there will be no collision. Suppose h < r1+r2. At the time of collision, the two sphere centers and the point of closest approach will form a right triangle. The distance from Sphere 1's center to the point of closest approach is
u = sqrt((r1 + r2)^2 - h^2)
So the distance sphere 1 has traveled is
s - u
Now just see if sphere 1 travels that far in the given interval. If so, then you know exactly when and where the spheres were (you must shift back from sphere 2's frame, but that's pretty easy). If not, there's no collision.
Closest approach can be done without simulating time if the position function is invertible and explicit.
Pick a path and object.
Find the point on the path where the two paths are closest. If time has bounds (e.g. paths are line segments), ignore the bounds in this step.
Find the time at which the object is at the point from the previous step.
If time has bounds, limit the picked time by the bounds.
Calculate the position of the other object at the time from the previous step.
Check if the objects overlap.
This won't work for all paths (e.g. some cubic), but should work for linear paths.

Resources