back-projecting a 2D point to 3D Plucker line - projection

I'm trying to build a tracker (hand tracking personal project), and for this reason I need to back-project a 2d point to a 3d line, using Plucker coordinates. (like ray tracing)
As an input, I have the 2d coordinates of a point and the projection matrix.
The information on the web about plucker coordinates give an overview of why they helpful, but there's no paper describing analytically the above mentioned procedure.
(they just mention that they back-project to a plucker line, without any further description)
Can somebody please pinpoint me to the right direction?

Apparently there's no magic behind this, I was looking for a formula/theorem resulting immediately from my 'inputs' to plucker coordinates, while there's no such thing.
As inputs, we have
2D coordinates of a (projected) point
the projection matrix
Using these two inputs, we can back-project this 2d point to a ray (3D line).
All 3D points of this 3D line are projected to the same 2D point.
The ray by default passes through the camera center (or projection center,etc).
For necessary equations, see
Hartley/Zisserman book # page 162 # equation 6.14, OR
Equation 23 -> http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/FUSIELLO4/tutorial.html
The general idea is that, in order to define a line, you need 2 points.
We choose to find (with equations from the above mentioned sources)
The camera center (all projection rays pass by default through this point)
A point of the ray # infinity (this is nice, because a point at infinity is also the direction vector of the line -> this is needed later-on for the plucker line representation)
(we could have found the camera center and another arbitrary point, but then we would need an extra step to find the direction of the line, by subtracting the coordinates of these two points.)
To sum up, we have found
The camera center (p)
The direction (d) of the line (point # infinity)
(Points at infinity are equivalent to directions)
These are enough to represent a line, but this representation is not optimal when we have to compute for example distances of 3D points to this line in our algorithm.
This is why, after finding this representation (no magic to give us plucker lines immediately), we change our line-representation to plucker-line-representation
Plucker line is just another representation of the line that needs:
The direction of the line (we already have it!!! -> d -> point at infinity)
The 'moment' (m) of the line, which is easy to compute from the previous representation:
m=p^d (^ -> cross product)
I hope this clears things for anyone that will need this in the future, I think it's a very easy thing, but in the beginning things might not be so apparent.
For a practical scenario, why one would use this plucker-line-representation, please check
http://files.is.tue.mpg.de/dtzionas/Hand-Object-Capture/IJCV_Hand_Object_Capture.pdf
https://pages.iai.uni-bonn.de/gall_juergen/download/jgall_tpami09.pdf

For future reference using Matlab / Octave syntax!
The join of two points in Plücker coordinates can be expressed as follows
% line = point join point
function L=join(A, B)
L=[
A(1)*B(2)-A(2)*B(1);
A(1)*B(3)-A(3)*B(1);
A(1)*B(4)-A(4)*B(1);
A(2)*B(3)-A(3)*B(2);
A(2)*B(4)-A(4)*B(2);
A(3)*B(4)-A(4)*B(3)
];
end % function
These are the 6 distinct values from the anti-symmetric matrix
Lx=B*A'-A*B'
A point on the backprojection ray can be found
X=pinv(P)*x
where
x=[u v 1]'
is the image point at pixel location (u,v) and
pinv(P)
the pseudoinverse of the projection matrix.
The camera center can be found as the null space of the projection matrix
C=null(P);
C=C/C(4)
The Plücker coordinates of the backprojection ray are thus
L=join(X,C)
For those interested in oriented projective geometry: If you normalize the projection matrix as follows
% Get length of principal ray
m3n=norm(P(3,1:3));
% Enforce positivity of determinant
if (det(P(:,1:3))<0)
m3n=-m3n;
end % if
% Normalize
P=P/m3n;
Then the determinant of the left 3x3 matrix is positive (i.e. right handed systems) and L will point from C to X.
Update: The other day, a co-worker asked me for a matrix-form solution. If you multiply the following matrix with an image point [x0 x1 x2]' you get the Plücker coordinates directly:
A=[
- p12*p23 + p13*p22, + p02*p23 - p03*p22, + p03*p12 - p02*p13
+ p11*p23 - p13*p21, - p01*p23 + p03*p21, + p01*p13 - p03*p11
- p11*p22 + p12*p21, + p01*p22 - p02*p21, + p02*p11 - p01*p12
- p10*p23 + p13*p20, + p00*p23 - p03*p20, + p03*p10 - p00*p13
+ p10*p22 - p12*p20, - p00*p22 + p02*p20, + p00*p12 - p02*p10
- p10*p21 + p11*p20, + p00*p21 - p01*p20, + p01*p10 - p00*p11
]
The line direction is therefore
d =
p01*p12*x2 - p02*p11*x2 - p01*p22*x1 + p02*p21*x1 + p11*p22*x0 - p12*p21*x0
p02*p10*x2 - p00*p12*x2 + p00*p22*x1 - p02*p20*x1 - p10*p22*x0 + p12*p20*x0
p00*p11*x2 - p01*p10*x2 - p00*p21*x1 + p01*p20*x1 + p10*p21*x0 - p11*p20*x0
and the line moment is:
m =
p03*p10*x2 - p00*p13*x2 + p00*p23*x1 - p03*p20*x1 - p10*p23*x0 + p13*p20*x0
p03*p11*x2 - p01*p13*x2 + p01*p23*x1 - p03*p21*x1 - p11*p23*x0 + p13*p21*x0
p03*p12*x2 - p02*p13*x2 + p02*p23*x1 - p03*p22*x1 - p12*p23*x0 + p13*p22*x0
Obviously, one can pull out the [x2 x1 x0] from the expression to get matrix form. The following MATLAB symbolic code was used to generate this solution:
syms p00 p01 p02 p03 p10 p11 p12 p13 p20 p21 p22 p23 real
P=[ p00 p01 p02 p03
p10 p11 p12 p13
p20 p21 p22 p23
]
% Some Image Point
syms x0 x1 x2 real
x=[x0 x1 x2]'
% Source Position
C=null(P)
% Backprojection of x
Xtilde=pinv(P)*x
% Backprojection line (Plücker Matrix)
Lx=simplify(C*Xtilde' - Xtilde*C')
% It's homogeneous...
arbitrary_scale=(p00*p11*p22 - p00*p12*p21 - p01*p10*p22 + p01*p12*p20 + p02*p10*p21 - p02*p11*p20)
Lx=Lx*arbitrary_scale
% Plücker Coordinates:
L=[Lx(1,2) Lx(1,3) Lx(1,4) Lx(2,3) Lx(2,4) Lx(3,4)];
% Direction
d=[-L(3) -L(5) -L(6)]';
% Moment
m=[L(4) -L(2) L(1)]';
% In matrix form
A=[
- p12*p23 + p13*p22, + p02*p23 - p03*p22, + p03*p12 - p02*p13
+ p11*p23 - p13*p21, - p01*p23 + p03*p21, + p01*p13 - p03*p11
- p11*p22 + p12*p21, + p01*p22 - p02*p21, + p02*p11 - p01*p12
- p10*p23 + p13*p20, + p00*p23 - p03*p20, + p03*p10 - p00*p13
+ p10*p22 - p12*p20, - p00*p22 + p02*p20, + p00*p12 - p02*p10
- p10*p21 + p11*p20, + p00*p21 - p01*p20, + p01*p10 - p00*p11
]
% Verification: (should be zero)
simplify(A*x - L')

I'm posting this just for the sake of completeness, based on a combination of some stuff in the paper cited in the OP's accepted answer, the answer by #André Aichert and the descriptions in p493 of [1].
The following is a minimally working MATLAB example for constructing the Plucker line passing through two points A and B and computing its distance to point C.
A = [0 0 0]';
B = [0 0 5]';
C = [1 1 0]';
L = pluckerline(A,B);
distance = compute_plucker_distance(C, L) % Will output 1.4142
%%-------------------------------------------------------------------------
% Comptes the Plucker line passing through points A and B
function L = pluckerline(A, B)
l = (B - A) / norm(B - A);
m = cross(A, l);
L = [l ; m];
end
%%-------------------------------------------------------------------------
% Comptes the distance between the point P and Plucker line L
function distance = compute_plucker_distance(P, L)
l = L(1:3);
m = L(4:end);
distance = norm(cross(P, l) - m);
end
[1] Sommer, Gerald, ed. Geometric computing with Clifford algebras: theoretical foundations and applications in computer vision and robotics. Springer Science & Business Media, 2013.

Related

Find a vector tangent to a circle

I need to move a point by vectors of fixed norm around a central circle.
So to do this, I need to calculate the circle tangent vector to apply to my point.
Here is a descriptive graph :
So I know p1 coordinates, circle radius and center, and the vector norm d. I need to find p2 (= finding the vector v orientation).
I put on the graph some ideas I got to find it : p1' is p1 projected on the circle. And t is the tangent vector to C in p1'.
That should be easy, but I'm too weak in maths to figure how to implement this. So I would like an idea of the implementation this (language agnostic is okay, javascript is cool).
Extra cool if you can also get me how to implement clockwise and counter clockwise movement with this.
Edit : Obtained this
let vx = cx - p1x,
vy = cy - p1y,
norm = Math.sqrt((vx * vx) + (vy * vy)),
p2x = p1x - (vy * d / norm),
p2y = p1y + (vx * d / norm);
But there is still a quirk : using this on time, the point is slowly getting away from the center of the circle, performing a spiral.
Obtain vector Center of circle - point P1. Let's call this vector
v1.
Tangent vector 't' is perpendicular to v1. If v1=(vx, vy) then
t=(-vy,vx) . Just swap values and a sign (I wrote -vy, it could also be -vx, but not both -vy,-vx).
Setting one direction or the order is just using t2= -t1= (vy, -vx), or (-vy, vx)
For movements you must use normalized (||v|| = 1) vectors.

Standard form of ellipse

I'm getting ellipses as level curves of a fit dataset. After selecting a particular ellipse, I would like to report it as a center point, semi-major and minor axes lengths, and a rotation angle. In other words, I would like to transform (using mathematica) my ellipse equation from the form:
Ax^2 + By^2 + Cx + Dy + Exy + F = 0
to a more standard form:
((xCos[alpha] - ySin[alpha] - h)^2)/(r^2) + ((xSin[alpha] + yCos[alpha] - k)^2)/(s^2) = 1
where (h,k) is the center, alpha is the rotation angle, and r and s are the semi-axes
The actual equation I'm attempting to transform is
1.68052 x - 9.83173 x^2 + 4.89519 y - 1.19133 x y - 9.70891 y^2 + 6.09234 = 0
I know the center point is the fitted maximum, which is:
{0.0704526, 0.247775}
I posted a version of this answer on Math SE since it benefits a lot from proper mathematical typesetting. The example there is simpler as well, and there are some extra details.
The following description follows the German Wikipedia article Hauptachsentransformation. Its English counterpart, according to inter-wiki links, is principal component analysis. I find the former article a lot more geometric than the latter. The latter has a strong focus on statistical data, though, so it might be useful for you nevertheless.
Rotation
Your ellipse is described as
[A E/2] [x] [x]
[x y] * [E/2 B] * [y] + [C D] * [y] + F = 0
First you identify the rotation. You do this by identifying the eigenvalues and eigenvectors of this 2×2 matrix. These eigenvectors will form an orthogonal matrix describing your rotation: its entries are the Sin[alpha] and Cos[alpha] from your formula.
With your numbers, you get
[A E/2] [-0.74248 0.66987] [-10.369 0 ] [-0.74248 -0.66987]
[E/2 B] = [-0.66987 -0.74248] * [ 0 -9.1715] * [ 0.66987 -0.74248]
The first of the three factors is the matrix formed by the eigenvectors, each normalized to unit length. The central matrix has the eigenvalues on the diagonal, and the last one is the transpose of the first. If you multiply the vector (x,y) with that last matrix, then you will change the coordinate system in such a way that the mixed term vanishes, i.e. the x and y axes are parallel to the main axes of your ellipse. This is just what happens in your desired formula, so now you know that
Cos[alpha] = -0.74248 (-0.742479398678 with more accuracy)
Sin[alpha] = 0.66987 ( 0.669868899516)
Translation
If you multiply the row vector [C D] in the above formula with the first of the three matrices, then this effect will exactly cancel the multiplication of (x, y) by the third matrix. Therefore in that changed coordinate system, you use the central diagonal matrix for the quadratic term, and this product for the linear term.
[-0.74248 0.66987]
[1.68052, 4.89519] * [-0.66987 -0.74248] = [-4.5269 -2.5089]
Now you have to complete the square independently for x and y, and you end up with a form from which you can read the center coordinates.
-10.369x² -4.5269x = -10.369(x + 0.21829)² + 0.49408
-9.1715y² -2.5089y = -9.1715(y + 0.13677)² + 0.17157
h = -0.21829 (-0.218286476695)
k = -0.13677 (-0.136774259156)
Note that h and k describe the center in the already rotated coordinate system; to obtain the original center you'd multiply again with the first matrix:
[-0.74248 0.66987] [-0.21829] [0.07045]
[-0.66987 -0.74248] * [-0.13677] = [0.24778]
which fits your description.
Scaling
The completed squares above contributed some more terms to the constant factor F:
6.09234 + 0.49408 + 0.17157 = 6.7580
Now you move this to the right side of the equation, then divide the whole equation by this number so that you get the = 1 from your desired form. Then you can deduce the radii.
1 -10.369
-- = ------- = 1.5344
r² -6.7580
1 -9.1715
-- = ------- = 1.3571
s² -6.7580
r = 0.80730 (0.807304599162099)
s = 0.85840 (0.858398019487315)
Verifying the result
Now let's check that we didn't make any mistakes. With the parameters we found, you can piece together the equation
((-0.74248*x - 0.66987*y + 0.21829)^2)/(0.80730^2)
+ (( 0.66987*x - 0.74248*y + 0.13677)^2)/(0.85840^2) = 1
Move the 1 to the left side, and multiply by -6.7580, and you should end up with the original equation. Expanding that (with the extra precision versions printed in parentheses), you'll get
-9.8317300000 x^2
-1.1913300000 x y
+1.6805200000 x
-9.7089100000 y^2
+4.8951900000 y
+6.0923400000
which is a perfect match for your input.
If you have h and k, you can use Lagrange Multipliers to maximize / minimize the function (x-h)^2+(y-k)^2 subject to the constraint of being on the ellipse. The maximum distance will be the major radius, the minimum distance the minor radius, and alpha will be how much they are rotated from horizontal.

transforming coordinates from one distorted coordinate system to another

the problem is best explained with an example:
http://dl.dropbox.com/u/1013446/distortedcoordinatespace.exe
drag and drop the little red square inside the small square on the right.
it corresponds to the red square in the big quadrilateral on the left.
you can also drag the 4 corners of the big quadrilateral on the left to see how it occupies a distorted version of the space within the square.
given the absolute coordinates for the 4 points of a square and the coordinates of an arbitrary point within the square, it's simple matter to remap the point's coordinates to an arbitrary quadrilateral.
what I want is to be able to start off with an arbitrary quadrilateral, and be able to do the same thing, transforming the quadrilateral to any other 4 sided shape, but maintaining the relative distorted position of the point,
so given the 4 absolute coordinates of each of 2 irregular quadrilaterals, A and B, how can I convert the coordinates of point C given it's absolute coordinates?
also helpful, would be any terminology that I'm missing here for what these transformations would be called, because I'd like to look into them more
ok, I'm attempting to implement btilly's solution, and here's what I have so far:
#include<complex>
#define cf complex<float>
cf i=sqrt(complex<float>(-1));
cf GetZ(float x,float y)
{
return cf(x)+(cf(y)*i);
}
cf GetPathIntegral(cf p1,cf p2,cf q1,cf q2, int n)
{
cf sum;
for (int index=0;index<=n;index++)
{
cf s=cf(float(index)/float(n));
cf weight;
if (index==0||index==n)
weight=1;
else if(index%2)
weight=4;
else weight =2;
sum+=(((cf(1)-s)*q1)+(s*q2))*(p2-p1)*weight;
}
return sum/cf((3.0*(n-1.0)));
}
before I move on from here, I want to make sure I'm right so far...
also, this paragraph confused me a bit:
OK, so we can do path integrals. What
is the value of that? Well suppose we
take a random point z0 = x + iy
somewhere in our region. Suppose that
f(z) is defined on the path. Then the
Cauchy Integral Formula says that the
integral around our region (which is
the sum of 4 piecewise integrals that
we know how to do) of f(z)/(2 * π * i
* (z - z0)) is a really nice function that is going to match our original
function on the boundary.
what does the function do exactly?
(My first pass was a complicated derivation of a natural seeming formula for this. But then I realized that there is a far, far better solution. Which I would have remembered earlier if I had used Complex Analysis in the last 20 years.)
The right way to do this is to apply the Cauchy Integral Formula. With this you can map any polygon to any other polygon. If the polygons don't self-intersect, it will send the boundary to the boundary and the interior to the interior. The mapping will also have the excellent property that it is conformal, meaning that angles are preserved. By that I mean that if a pair of curves intersect in your region, then they will be mapped to a pair of curves that intersect at the same angle. (Many of Escher's drawings are based on conformal mappings.)
Enough hype. How do you do it? I'll explain it, assuming that you know absolutely nothing about complex analysis. I'll use some Calculus terms, but you should be able to follow my directions even if you don't know any Calculus at all. Since I am assuming so little, the explanation has to be kind of long. I'm sorry for that.
Every point (x, y) in the real plane can be viewed as a complex number z = x + iy. We can add and multiply complex numbers using the usual rules of algebra and the fact that i * i = -1. Furthermore note that 1 = (x + iy) * (x - iy)/(x2 + y2) so we can divide if we let 1/z = (x - iy)/(x2 + y2). We therefore have all of the usual rules of arithmetic.
But we can do better than that. We can do Calculus. In particular we can do path integrals around curves. An integral of a function along a curve is a kind of weighted average of that function over the points in that curve. You can read up on how to do it in general. But here is how to do it in this case.
Suppose that the starting region has corners P1, P2, P3, P4. The path around the region is defined by the four line segments (P1, P2), (P2, P3), (P3, P4), (P4, P1). I'll talk about how to handle the first line segment. The others are similar.
The path integral of f(z) over (P1, P2) is the integral from 0 to 1 of f((1-s)P1 + sP2)(P2 - P1). To evaluate that integral, the easiest thing to do is numerical integration using Simpson's Rule. To do this pick an odd number n and for the values s = 0, 1/n, 2/n, ..., (n-1)/n, 1 assign them weights in the pattern 1, 4, 2, 4, 2, ..., 2, 4, 1. (The end points are 1, everything else alternates between 4 and 2.) Now for each point calculate f((1-s)P1 + sP2)(P2 - P1), multiply by the weight, and add them all together. Then divide by the magic value 3 * (n-1). The result is approximately your integral. (As n grows, the error in this approximation is O(1/n4). In your case if you take n = 21 then the approximation should wind up good enough to map pixels to the right pixel, except for some pixels near the boundary. Make it a little larger, and the problematic area will get smaller. Right at the edge you'll want some multiple of the number of pixels on a side to make the error small .)
OK, so we can do path integrals. What is the value of that? Well suppose we take a random point z0 = x + iy somewhere in our region. Suppose that f(z) is defined on the path. Then the Cauchy Integral Formula says that the integral around our region (which is the sum of 4 piecewise integrals that we know how to do) of f(z)/(2 * π * i * (z - z0)) is a really nice function that is going to match our original function on the boundary. I won't get into all of the "really nice" things about it, but what I was saying above about conformal is part of it.
Now what function f do we use? Well suppose that our region is being mapped to a region with corners Q1, Q2, Q3, Q4. We want the first path piece to map to the second path piece. So we want f((1-s)P1 + sP2) to be (1-s)Q1 + sQ2. That tells us how to calculate f at all of the points we need to do our integral.
Now, you ask, how do you reverse it? That's simple. Just reverse the role of the two polygons, and calculate the reverse transformation! Which brings a really good unit test. You should define a couple of weird regions, pick a point in the middle, and verify that if you map from the first to the second and back again that you wind up close to where you started. If you pass that test, then you probably have made no mistakes.
And finally what about my general polygon claim that I made? Well we defined our path as four pieces we traversed linearly. A higher degree polygon just has more pieces to its path, but otherwise the calculation is done in exactly the same way.
found the solution. I have to say, it's much more complicated than I had expected:
assuming a square or quadrilateral has the four corners:
AB
CD
you need an interpolation factor: xt for the x axis, and yt for the y axis, so that
if you define a linear interpolation formula:
lerp(j,k,t)
{
return (t*(k-j))+j;
}
a point p within the ABCD quad is defined as:
p.x=lerp(lerp(a.x,b.x,xt),lerp(c.x,d.x,xt),yt)
and
p.y=lerp(lerp(a.y,c.y,yt),lerp(b.y,d.y,yt),xt)
then the values you need to define are xt and yt
xt= ((2* c.x* a.y) - (d.x* a.y) - (2
*a.x c.y) + (b.x c.y) - (c.x* b.y) + (a.x* d.y) - (a.y* p.x) + (c.y* p.x )+
(b.y p.x) - (d.y p.x) + (a.x p.y)
- (b.x p.y) - (c.x* p.y) + (d.x* p.y) - Sqrt(-4* ((c.x* a.y) - (d.x*
a.y) - (a.x* c.y) + (b.x* c.y) - (c.x*
b.y) + (d.x* b.y) + (a.x d.y) -
(b.x d.y))* ((c.x* a.y) - (a.x* c.y)
- (a.y* p.x) + (c.y* p.x) + (a.x* p.y) - (c.x* p.y)) + ((-2 *c.x a.y) + (d.x a.y) + (2 *a.x c.y) - (b.x
c.y) + (c.x* b.y) - (a.x* d.y) + (a.y*
p.x) - (c.y* p.x) - (b.y* p.x) + (d.y*
p.x) - (a.x* p.y) + (b.x* p.y) +
(c.x* p.y) - (d.x p.y))^2))/(2
((c.x* a.y) - (d.x* a.y) - (a.x* c.y)
+ (b.x* c.y) - (c.x* b.y) + (d.x *b.y) + (a.x *d.y) - ( b.x *d.y)))
and once you have that
yt=(p.x-lerp(a.x,b.x,('xt')))/(lerp(c.x,d.x,('xt'))-lerp(a.x,b.x,('xt')))

Minimal perpendicular vector between a point and a line

Okay so I'm trying to get a separating axis theorem algorithm to work (for collision detection) and I need to find the minimal perpendicular vector between a point and a line. I'm not asking for the minimum perpendicular distance (which I know how to find) but rather the vector that would have the same magnitude as that distance and that goes from an arbitrary point and a point on the line. I know the location of the point, a point on the line, and a unit vector giving the direction of the line.
What I tried doing was first finding the minimal distance between the point and the line.
The next part is confusing but I:
1) Found the vector between the point and the point on the line I know
2) Found the vector between the point on the line and the point on the line plus the unit vector giving the direction of the line
3) Took the cross product of these two vectors (I'll call this cross product A)
4) Took the cross product of the unit vector giving the direction of the line and the vector from cross product A (I'll call this cross product B)
5) Normalized cross product B
6) Scaled cross product B by the minimal distance
Anyways that whole attempt failed miserably. Can anyone tell me how I am supposed to find this vector?
If I understood your question correctly, I believe this is what you're looking for:
P - point
D - direction of line (unit length)
A - point in line
X - base of the perpendicular line
P
/|
/ |
/ v
A---X----->D
(P-A).D == |X-A|
X == A + ((P-A).D)D
Desired perpendicular: X-P
where the period represents the dot product and |X-A| means magnitude.
From the above figure, you have:
q = p + s --> s = q - p = q - (p2-p1) = q + p1 - p2
==> s^ = |q - p2 - p1| / |s| (unitary vector)
Also: |s| = |q| sin c = |q|sin(b-a)
b = arcsin (qy / |q|); a = arcsin( p1y / |p1| )
where: |q| = (qx^2 + qy^2)^1/2

Determining if and where a photon will collide with a polygon in 3D space

The problem is straight forward:
1) We have a photon traveling from Point 1 (x,y,z) to Point 2 (x,y,z), both of which could be located anywhere in 3D space.
2) We have a polygon that is both rotated randomly on the x-axis and/or y-axis and also located anywhere in 3D space.
3) We want to find: a) if the photon will collide with the polygon at all and b) if it does where will that be (x,y,z)?
An image of the problem: http://dl.dropbox.com/u/3150177/Programming/3D/Math/Photon%20Path/Photon%20Path.png
The aim of this is to calculate how the photon's path should be altered from an interaction(s) with the polygon(s).
I am reading up on this subject now but I was wondering if anyone could give me a head start. Thanks in advance.
Sounds like you are looking for a ray/polygon intersection test.
I can't remember the details but I imagine you split it into two parts. First you find the point on the polygon's plane that the ray intersects at. This can be got from a simple ray/plane intersection test. Secondly use a co-ordinate system on the polygon's plane to test whether the intersection point lies within the polygon. This can be got from a point-in-polygon test.
General overview:
1) Segment-Plane Intersection: Determine if the line segment connecting points 1 and 2 intersects the plane containing the polygon. If it doesn't, then it will never intersect the polygon, and you're done.
2) Find Point of Intersection: Determine the point at which the line segment and plane intersect. This will provide the information you want in 3-b in your question. Call this point Q
3) Determine if Q is interior to the polygon: One method of determining this is here, but a well crafted Google search will likely result in others. You can optimize for different types of polygons you expect (i.e. convex) or if the plane containing the polygon is axially aligned (i.e. one of the axes for your coordinate system is normal to the plane containing the polygon).
Assumption: All of the polygon's points are co-planar.
You're doing ray tracing. Most efficient is to break the polygon into triangles and use the Moeller ray-triangle test. Or perhaps the Wald test. There are also variants that use extra stored data beyond just the vertex information which can be even faster if you're doing multiple rays against the same triangle. Google provides so many results, I haven't selected a "best" one to put here.
The photon is traveling with vector v = p2 - p1 starting at p1, creating this line:
p1 + v * a
To find out if the photon collides with the polygon you have to find a value for a for:
p1 + v * a = polygon
For example:
p1 is (15, 4, 5)
p2 is (10, 1, 3)
and polygon is a 10x10 square: (-5...5, -5...5, 0)
v = p2 - p1 = (-5, -3, -2)
p1 + v * a = pol makes:
p1.x + v.x * a = pol.x
p1.y + v.y * a = pol.y
p1.z + v.z * a = pol.z
a = (pol.z - p1.z) / v.z = (0 - 15) / -2 = 7.5
pol.x = p1.x + v.x * a = 15 + -5 * 7.5 = -22.5
pol.y = p1.y + v.y * a = 10 + -3 * 7.5 = -12.5
The -22.5 is not between -5 and 5 and -12.5 is not between -5 and 5, so the photon does not collide with the polygon.
It's been a while since I've done this so I may have made some mistakes. I used the fact that pol.z = 0 to calculate a. You may have to rotate the polygon to line up with one axis, as long as you rotate p1 around the polygon's center as well.
Ray / triangle intersections are well understood and quite easy. The rotations are harder, though.
Perhaps you could transform the triangle's vertices using a rotation matrix and then use a simple ray / triangle intersection?

Resources