The first function checks a point against a plane since a rectangle or most polygons (2d) or polyhedrons in 3d are convex the object itself can form a set of bounding collision planes.
In the case of a simple rectangle it is comprised of 4 points.
Rectangle r = new Rectangle(0,0,1,1);
Vector2 A = new Vector2(r.Left, r.Top);
Vector2 B = new Vector2(r.Right, r.Top);
Vector2 C = new Vector2(r.Right, r.Bottom);
Vector2 D = new Vector2(r.Left, r.Bottom);
These points from the top left of the rectangle proceed to the top right then down clockwise ect.,, Such that the first two points A to B form a edge line of the rectangle to top edge of the rectangle (from top left to top right (the corners are the vector points), which can also be considered a collidable bounding plane of the rectangles top edge (though we only have its end points to start with). This continues on B to C the right edge C to D the bottom edge D to A the left edge. The function itself takes a start and end parameter for this reason start and end denote the end points of a line but which point we pass as start and end is actually important so we name the parameters to follow that idea.
This line which we will treat as a 2 dimensional plane we will want to think of as a real solid surface but mathematically turn that idea into a check we can actually use. This line from point to point is used by the function itself with the thought that it is a descriptor of a 2d surface so to do this.... It takes the line and finds a cross product Vector to get what can be considered a surface normal or creates a right angle point to that line or for us are imaginary rectangle's side surface normal or if you like a perpendicular line to a rectangles side though we will need one per side of our rectangle to do a full check so this function creates them on the fly.
It also takes the collision point - the start point to find a direction vector to the collision point it doesn't treat that as if its a plane it treats it as if it is already a seperate distinct surface normal from another object itself.
Before i continue i would briefly remind you of the operational results of the dot product.
As you may know the dot product works off of directions like two hands of a clock it treats them as if always upon the orgin or attached to the center of the clock (no matter how the original vectors to them were positioned) It measures the angle or theta of the difference between the hands of this imaginary clock, now are lines have ends these are vectors but we turn them into directions that is one hand of the imaginary clock The collision point will be used to form the other. The end points of the rectangle wind around the rectangle clockwise that is if we pass them in order a,b then b,c then c,d ect... Remember now the top line A to B pass this as the start and end to our original function test...
The function will find the following directions.
B - A = d1 and CollisionPoint - A = d2
Now if we were to dot these directly to each other to find the theta(angle of difference), the dot(d1,d2) will return a value in the range of -1 to 1 for normalized vectors. The range is not what really matters in our case. Its if you get the negative or positive back. A value of -1 the negative aspect denotes that the two hands of the imaginary clock point in opposite directions. Where a value of 1 denotes they point together in a similar direction.
a value of zero indicates that they are perpendicular to each other _|.
Now what the below code will do is take the A-B line passed, (were A is the start parameter) and use the right hand rule to create a point to the right of the direction of the vector Which is defined as the End minus the Start such that the direction is then A to B
(which you can image with your right hand pointing in the A to B direction and your thumb then becoming the cross products point, you may then image the starting point of your rectangle with your right hand at the top left of a rectangle pointing to the top right point from there, you may visualize going around to each point to see the cross normal will always point inward for each line and your finger itself forms the surface direction) .
Finally then this line of code dots to the collision point minus the starting point (A in this case) that point is not crossed as it is a normal to the point checked for collision, so that is only doted to the cross vector of the line, i have crunched both into one here.
This is two operations at the same time which i condensed.
It is a right handed cross product of B - A = n0 and then a dot product against Collision - A = n1.
So its then dot(n0,n1).
float sign = A.X * B.Y + A.Y * -B.X`;
These 2 lines below just ensures the math to the modified dot product function comes out right because the dot portion has a addition element negated, and removes the need for a square root here. Normalizing a and b would probably work as well.
A = (A * A) / (A.X * A.X + A.Y * A.Y);
B = (B * B) / (B.X * B.X + B.Y * B.Y);
Note that rotation in this type of plane function makes no difference to how the check is made, since we are working on planes and points directly, regardless of the orientation of them. E.G. you can get the vector points then rotate each with matrix.Tanslate(...)j.
You can manually rotate the points if you want yourself it probably cheaper then doing building a matrix ect.
public static Vector2 Rotate2dPointAboutOriginOnZaxis(Vector2 p, Vector2 o, double q)
//x' = x*cos s - y*sin s , y' = x*sin s + y*cos s
double x = p.X - o.X; // transform locally to the orgin
double y = p.Y - o.Y;
double rx = x * Math.Cos(q) - y * Math.Sin(q);
double ry = x * Math.Sin(q) + y * Math.Cos(q);
p.X = (float)rx + o.X; // translate back to previous non local
p.Y = (float)ry + o.Y;
Now if we have two Rectangles or polygons each of the points of one can be processed against each line of the other. As soon as one of the test fails to pass the test can end in the case of a rectangle a point must pass 4 line tests to be inside the rectangle. This is the extent of the idea in its brute force form this can be smartened up further it can also be used within a collision grid collision grids can be made to accept polygons even under rotation.
The second formula posted is a old line to line test i found on the comp graphics forum. http://www.faqs.org/faqs/graphics/algorithms-faq/ (great algorithm archive scroll way down). I reduced this a little bit but its basically the same formula.
You can probably look up 10 or 20 of these line to line intersection tests on the net in a few minutes and find 10 or 20 that are Wrong !
This is a correct version this uses a quadratic to find two possible times of collision. (while this returns a result based on t. I was under the impression you should use the lesser of t or u provided it is not negative).
However this pretty much just works.
It takes two lines (which could be the sides of two different rectangles) and simply sees if they cross if so it returns true and gives the point of intersection on one of the lines.