Reputation: 11808
I have this code in GLSL which looks like this:
float Intersect(vec2 lineOneStart, vec2 lineOneEnd, vec2 lineTwoStart, vec2 lineTwoEnd) {
vec2 line2Perp = vec2(lineTwoEnd.y - lineTwoStart.y, lineTwoStart.x - lineTwoEnd.x);
float line1Proj = dot(lineOneEnd - lineOneStart, line2Perp);
if (abs(line1Proj) < 0.0001) {
return 0.;
}
return dot(lineTwoStart - lineOneStart, line2Perp) / line1Proj;
}
I have drawn up a visualization of what I think this coding is doing, in the following illustration:
Hopefully that image is correct, if not please let me know.
Basically, I am trying to write a function that, given two line segments, returns the distance from lineOneStart
to the intersection point in lineTwo
. In reality, lineOne extends forever in its direction, but for simplicity I just gave it a very long length such that it will always reach lineTwo
.
I obtained this code from elsewhere, but the problem is I don't understand how it works, or even if it is working. I obtained the code from the demo posted at the bottom of this article
In the article, the author describes the code as the following:
...Compute the intersection point between and the line segment and the light ray at the current angle, but this is just a couple of dot products and a divide, so nothing too heavy for a modern GPU.
But it doesn't really seem to be doing that? In that the first line of the function seems to make the line go to the start of lineTwo
, rather than along its angle to the closest intersection point.
In addition, the dot product has always been mystifying to me, so I'm having trouble seeing how two dot products here is giving me the claimed result. Is this code correct, and if so, how does it work?
Upvotes: 1
Views: 122
Reputation: 210998
If you've a endless line which is defined by a point P
and a normalized direction R
and a second endless line, which is defined by a point Q
and a direction S
, then the intersection point of the endless lines X
is:
alpha ... angle between Q-P and R
beta ... angle between R and S
gamma = 180° - alpha - beta
h = | Q - P | * sin(alpha)
u = h / sin(beta)
t = | Q - P | * sin(gamma) / sin(beta)
t = dot(Q-P, (S.y, -S.x)) / dot(R, (S.y, -S.x)) = determinant(mat2(Q-P, S)) / determinant(mat2(R, S))
u = dot(Q-P, (R.y, -R.x)) / dot(R, (S.y, -S.x)) = determinant(mat2(Q-P, R)) / determinant(mat2(R, S))
X = P + R * t = Q + S * u
In general The dot product of 2 vectors is equal the cosine of the angle between the 2 vectors multiplied by the magnitude (length) of both vectors.
dot( A, B ) == | A | * | B | * cos( angle_A_B )
In your case line2Perp
is (S.y, -S.x)
:
vec2 line2Perp = vec2(lineTwoEnd.y - lineTwoStart.y, lineTwoStart.x - lineTwoEnd.x);
line1Proj
is dot(R, (S.y, -S.x))
:
float line1Proj = dot(lineOneEnd - lineOneStart, line2Perp);
and lineTwoStart - lineOneStart
is Q-P
:
return dot(lineTwoStart - lineOneStart, line2Perp) / line1Proj;
Upvotes: 1