Determining relative angular orientation of vectors
10 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I am trying to implement Snell's law, but I am currently lacking an elegant way to take into account the angular orientation/direction into which I need to rotate my vector. Quick and dirty example:
%choose incident vector and intersection points with circle
vector = [1 ; 0];
P1 = [-sqrt(0.0075); 0.05];
P2 = [-sqrt(0.0075); -0.05];
%for both points, calculate the angle between the incident vector and the
%normal
theta1 = real(acos(max(min(dot(vector, -P1) / (vecnorm(vector) * vecnorm(P1))))));
theta2 = real(acos(max(min(dot(vector, -P2) / (vecnorm(vector) * vecnorm(P2))))));
%snell's law
alpha1 = asin((sin(theta1)/1.6));
alpha2 = asin((sin(theta2)/1.6));
%rotate the normal vector by the refracted angle (*10 so the length is the
%same as for version 2)
new_vec1 = rot_matrix_2d(-P1, -alpha1)*10;
new_vec2 = rot_matrix_2d(-P2, alpha2)*10;
%version 2: rotate incident vector by difference between incident and
%refracted angle
new_vec1_v2 = rot_matrix_2d(vector, (theta1-alpha1));
new_vec2_v2 = rot_matrix_2d(vector, -(theta2-alpha2));
%definition of the rotation matrix
function rot_vec = rot_matrix_2d(vec, theta)
R = [cos(theta) sin(theta) ; -sin(theta) cos(theta)];
rot_vec = R * vec;
end
I have a vector (or rather two) that goes to the right and want to make it refract on a circular surface at two points (x0 = y0 = 0, r = 0.1). The upper vector should, after refraction, go to the bottom right, while the lower vector should go to the upper right. P1 and P2 are the intersection points of the vector(s) and the circle, and as such, -P1 and -P2 are also the normals. The issue basically starts when determining the angle, since theta1 = theta2 in value. However, in one case, the angle describes a rotation in clockwise direction, and in the other case, it is counter clockwise.
Getting the refracted vector can be done by either rotating the normal by the angle after refraction (here with index of refraction n = 1.6), or by rotating the original vector by the difference between the refracted angle and the angle of incidence (delta). However, as you can see, in one case I need to rotate by -alpha, while in the other case, I need to rotate by alpha (or delta and -delta). Is there an easy way to determine into which direction I need to rotate? I want to make this generically applicable.
8 commentaires
Matt J
le 29 Mar 2022
To put it this way: the ray "crosses" the normal, it continues on the "other side".
Apparently it is possible to have a negative index of refraction, in which case the beam will not cross the normal:
Réponse acceptée
Matt J
le 28 Mar 2022
Modifié(e) : Matt J
le 28 Mar 2022
Perhaps as follows?
vector = [1 ; 0];
P1 = [-sqrt(0.0075); 0.05];
P2 = [-sqrt(0.0075); -0.05];
new_vec1 = refract(vector,P1,1.6)
new_vec2 = refract(vector,P2,1.6)
function refractedVector = refract(vector,normal,snellFactor)
vector=vector(:)/norm(vector);
normal=normal(:)/norm(normal);
normal = sign( dot(vector,normal) )*normal; %direct the normal so that incident angle is acute
alpha= asin( sin( acos( dot(vector,normal) ) ) /snellFactor ); %Snell's law
s=sign( det([vector,normal])); %s<0 ==> clockwise
antinormal=normal([2,1]).*[1;-1].*s;
refractedVector=normal+tan(alpha)*antinormal;
refractedVector=refractedVector/norm(refractedVector);
end
Plus de réponses (1)
Bruno Luong
le 28 Mar 2022
Modifié(e) : Bruno Luong
le 28 Mar 2022
No need to call costly trigonometric functions
% Direction of incidence Ray (normalized)
Rayi = randn(2,1);
Rayi = Rayi/norm(Rayi);
% Direction of normal vector (normalized)
Normal = randn(2,1);
Normal = Normal/norm(Normal);
% Refractive index, n1 on incidence side, n2 on refraction side
n1 = 1;
n2 = 1.6;
Tangent = [0 -1; 1 0]*Normal;
Ci = dot(Rayi,Normal);
Si = dot(Rayi,Tangent);
Sr = (n1/n2)*Si;
if abs(Sr) > 1
% Should never get here if n2 > n1
fprintf('Total reflexion: No refraction ray\n')
return
end
Cr = sign(Ci)*sqrt(1-Sr^2); % NOTE: The sign(Ci) can be removed if N is by convention pointed from n1 to n2 medium.
Rayo = Cr*Normal + Sr*Tangent;
Rayi
Normal
Rayo
6 commentaires
Bruno Luong
le 31 Mar 2022
Modifié(e) : Bruno Luong
le 31 Mar 2022
For amplitude as well as direction, you don't need the angles, all you need are (square of) sine and cosine of different rays, which is given by (incident, transmitted and reflexion):
- cosine(thetai) = Ci
- sine(thetai) = Si
- cosine(thetat) = Cr
- sine(thetat) = Sr
- cosine(thetar) = Ci
- sine(thetat) = Si
Voir également
Catégories
En savoir plus sur Propagation and Channel Models dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!