1
\$\begingroup\$

I have a three objects (strikers), lets say red, green and blue.

When I apply force to the green object I want to check if it has passed between red and blue or not. See the image below for an illustration.

Is there any line collider or something for that?

enter image description here

\$\endgroup\$
  • 2
    \$\begingroup\$ Should this work on 2D or 3D? \$\endgroup\$ – Leo Feb 13 '15 at 13:38
  • \$\begingroup\$ Are blue and green moving? \$\endgroup\$ – Johan Holtby Feb 13 '15 at 15:25
  • \$\begingroup\$ yes both object also moving and this is in 2D \$\endgroup\$ – Hardik Nadiyapara Feb 14 '15 at 5:17
  • \$\begingroup\$ Can you cast a ray from the blue to red? If so, can you determine if the ray is "touched" by the green? \$\endgroup\$ – MVCDS Jul 14 '15 at 15:41
3
\$\begingroup\$

You can use vectors, they're quite handy in fact. Oddly enough you'll need to use 3D vectors to accomplish this 2D task, but it's all rather straight forward.

First let's look at how to figure out if the test ball is in the "corridor" between the other balls. To do this we'll use the dot products of the vectors between all 3 balls.

enter image description here

The dot product can be thought of telling if two vectors are in the same direction. We'll do one test for each ball we might be moving between. We check to see that our test ball, shown in dark blue labelled C, is in the same direction as the other light blue ball. From B's perspective, we take the vector from B to A (BA) and do it with the vector from B to C (BC). If it's positive, then C is in the same direction as A (the angle between them is less than 90 degrees).

Lastly we'll use a cross product to determine if the dark blue ball C has cross between B and A. This trick uses 3D vectors, but it's still quite simple.

Crazy Cross Products

We'll perform one cross product per-frame of your game, and keep the result around to look at in the next frame. Looking in the perspective of B, we'll do BC × BA and inspect the third component, the value in the Z direction. If the sign of (BC × BA).Z changes between frames, we know that the ball has moved to the other side of the BA line. This is due to the way cross products are computed, if the vectors swap sides basically the sign of the cross product will be inverted.

In short, check that the dot products are both positive like I described, and if the sign of the cross product changes between frames, the ball has crossed the line in one direction or the other. If you're interested in a code sample I could provide one if this doesn't make sense as abstract as it is.

\$\endgroup\$
1
\$\begingroup\$

Check X any Y boundaries for the respective objects.

visualization of x,y boundaries that need checking

So, basically you want your object's X value to be be greater than RED's X value and less than BLUE's X value (so it's horizontally between them), and your object's Y value to be less than the max Y value RED/BLUE (whichever has a greater Y, less than that). When it passes the lower Y value then you note that it passed that and wait for it to pass the greater Y value.

To roll your own here will take a little thinking, particularly if the goal posts (the RED/BLUE objects move) and especially if they move independently. If they are always fixed (game of marbles) when checking this stuff then you can first test to see whether they are vertical or horizontal, relative to each other, and have slightly different sets of checks. Presumably you'd need to calculate distance to objects and figure which pairs of objects you might potentially pass through.

Because these are spheres, you either have to track two X values and two Y values (respective straight line edges) or calculate those two values from the coordinates of the sphere's center and it's radius.

enter image description here

I suppose if you can construct two right triangle by drawing a line connecting the spheres and so, then you need only check if if the ball passes either or both of straight lines that comprise the outside of the triangles(i.e. ball X,Y intersected the line)...

As suggested above, some kind of linear algebra would probably simplify this a bit. I forget exactly how to apply it but you're effectively testing intersection with a line inside a certain domain.

If you know the equation of the line that describes the object's current motion (movement/velocity vector?) and the equation of the line between the two objects then the solution to the system of equations (i.e. those two -- two eqns, two unknowns?) there would be the intersection point. If there is any solution inside the domain then you have a potential collision point. You could get the slope of line with the distance between the two points (RED/BLUE sphere centers).

slope = rise/run = (Y2-Y1)/(X2 - X1)

http://en.wikipedia.org/wiki/System_of_linear_equations
^ You need the line in standard form for this

basic example of how to solve them: http://www.mathsisfun.com/algebra/systems-linear-equations-matrices.html

I think you are only dealing with X,Y here so it is line intersections between two lines. Collision is, I guess, there being a solution to the system and your object being at/close to/past the point of intersection

\$\endgroup\$
0
\$\begingroup\$

This method is kind of a hack and will not work at high speeds. Try it out and see if it fits your needs.

This will tell you the position of the Green point relative to the line formed by Red and Blue:

side = (Blue.x-Read.x)(Green.Y-Red.y) - (Blue.y-Red.y)(Green.X-Red.x)

  • If side = 0: Green is rigth in the middle of Blue and Red.
  • If side < 0: Green is on one side of the line
  • If side > 0: Green is on the other side

You should store this value for Green, and update it. Then, the moment the sign changes, you need to check:

  • If (Red-Green)·(Blue-Green) < 0 : Then Green point passed between both points

  • Else : It didn't

\$\endgroup\$
  • \$\begingroup\$ This is very close to working, but will report a cross even if green is not between red and blue and crosses the red/blue line. For example if green is up and to the left of red, it will cross the red/blue line and the quantity you described will still change signs. \$\endgroup\$ – Alex Sherman Aug 13 '15 at 5:42
0
\$\begingroup\$

Can you cast a ray from the blue to red? If so, can you determine if the ray is "touched" by the green? – MVCDS

Yes, using a CircleCollider2D and Linecast(...);

if (Physics.Linecast(redPosition, bluePosition))
{
  //The line intersects a collider
  ...
}

http://docs.unity3d.com/ScriptReference/Physics.Linecast.html

I've never used Unity, so I can't say whether this functionality was available at the time of asking.

\$\endgroup\$
-1
\$\begingroup\$

Use triangle space determinat computation - if you can observe all three points... It should change sign in front of space number after crossing line. Other way is to count angle between points with needle on green when it gets over 180 degree it is behind ;)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.