TP-traitement-audio-visuel/TP9/calcul_W.m
2023-06-22 20:47:16 +02:00

118 lines
3.6 KiB
Matlab

function W = calcul_W(N, theta, p)
d = p - 1;
% Define the number of angles.
nA = length(theta);
% The starting values both the x and the y coordinates.
x0 = linspace(-d / 2, d / 2, p)';
y0 = zeros(p, 1);
% The intersection lines.
x = (-N / 2:N / 2)';
y = x;
% Initialize vectors that contains the row numbers, the column numbers
% and the values for creating the matrix W efficiently.
rows = zeros(2 * N * nA * p, 1);
cols = rows;
vals = rows;
idxend = 0;
II = 1:nA;
JJ = 1:p;
% Loop over the chosen angles.
for i = II
% All the starting points for the current angle.
x0theta = cosd(theta(i)) * x0 - sind(theta(i)) * y0;
y0theta = sind(theta(i)) * x0 + cosd(theta(i)) * y0;
% The direction vector for all rays corresponding to the current angle.
a = -sind(theta(i));
b = cosd(theta(i));
% Loop over the rays.
for j = JJ
% Use the parametrisation of line to get the y-coordinates of
% intersections with x = constant.
tx = (x - x0theta(j)) / a;
yx = b * tx + y0theta(j);
% Use the parametrisation of line to get the x-coordinates of
% intersections with y = constant.
ty = (y - y0theta(j)) / b;
xy = a * ty + x0theta(j);
% Collect the intersection times and coordinates.
t = [tx; ty];
xxy = [x; xy];
yxy = [yx; y];
% Sort the coordinates according to intersection time.
[~, I] = sort(t);
xxy = xxy(I);
yxy = yxy(I);
% Skip the points outside the box.
I = (xxy >= -N / 2 & xxy <= N / 2 & yxy >= -N / 2 & yxy <= N / 2);
xxy = xxy(I);
yxy = yxy(I);
% Skip double points.
I = (abs(diff(xxy)) <= 1e-10 & abs(diff(yxy)) <= 1e-10);
xxy(I) = [];
yxy(I) = [];
% Calculate the length within cell and determines the number of
% cells which is hit.
aval = sqrt(diff(xxy).^2 + diff(yxy).^2);
col = [];
% Store the values inside the box.
if numel(aval) > 0
% If the ray is on the boundary of the box in the top or to the
% right the ray does not by definition lie with in a valid cell.
if ~((b == 0 && abs(y0theta(j) - N / 2) < 1e-15) || ...
(a == 0 && abs(x0theta(j) - N / 2) < 1e-15))
% Calculates the midpoints of the line within the cells.
xm = 0.5 * (xxy(1:end - 1) + xxy(2:end)) + N / 2;
ym = 0.5 * (yxy(1:end - 1) + yxy(2:end)) + N / 2;
% Translate the midpoint coordinates to index.
col = floor(xm) * N + (N - floor(ym));
end
end
if ~isempty(col)
% Create the indices to store the values to vector for
% later creation of W matrix.
idxstart = idxend + 1;
idxend = idxstart + numel(col) - 1;
idx = idxstart:idxend;
% Store row numbers, column numbers and values.
rows(idx) = (i - 1) * p + j;
cols(idx) = col;
vals(idx) = aval;
end
end % end j
end % end i
% Truncate excess zeros.
rows = rows(1:idxend);
cols = cols(1:idxend);
vals = vals(1:idxend);
% Create sparse matrix W from the stored values.
W = sparse(rows, cols, vals, p * nA, N^2);