Poszukuję prostego sposobu na utworzenie losowego wektora jednostkowego ograniczonego przez obszar stożkowy. Pochodzenie jest zawsze [0,0,0].Utwórz wektor losowy w określonym obszarze stożkowym
Moje rozwiązanie do tej pory:
function v = GetRandomVectorInsideCone(coneDir,coneAngleDegree)
coneDir = normc(coneDir);
ang = coneAngleDegree + 1;
while ang > coneAngleDegree
v = [randn(1); randn(1); randn(1)];
v = v + coneDir;
v = normc(v);
ang = atan2(norm(cross(v,coneDir)), dot(v,coneDir))*180/pi;
end
Mój kod pętle aż losowo generowany wektor jednostkowy jest wewnątrz zdefiniowanego stożka. Czy jest lepszy sposób to zrobić?
Wynikowy obraz z kodem testowym poniżej
wynikowego rozkładu częstotliwości z wykorzystaniem Ahmed Fasih kod (w komentarzach). Zastanawiam się, jak uzyskać rozkład prostokątny lub normalny.
c = [1;1;1]; angs = arrayfun(@(i) subspace(c, GetRandomVectorInsideCone(c, 30)), 1:1e5) * 180/pi; figure(); hist(angs, 50);
kod
Testowanie:
clearvars; clc; close all;
coneDir = [randn(1); randn(1); randn(1)];
coneDir = [0 0 1]';
coneDir = normc(coneDir);
coneAngle = 45;
N = 1000;
vAngles = zeros(N,1);
vs = zeros(3,N);
for i=1:N
vs(:,i) = GetRandomVectorInsideCone(coneDir,coneAngle);
vAngles(i) = subspace(vs(:,i),coneDir)*180/pi;
end
maxAngle = max(vAngles);
minAngle = min(vAngles);
meanAngle = mean(vAngles);
AngleStd = std(vAngles);
fprintf('v angle\n');
fprintf('Direction: [%.3f %.3f %.3f]^T. Angle: %.2fº\n',coneDir,coneAngle);
fprintf('Min: %.2fº. Max: %.2fº\n',minAngle,maxAngle);
fprintf('Mean: %.2fº\n',meanAngle);
fprintf('Standard Dev: %.2fº\n',AngleStd);
%% Plot
figure;
grid on;
rotate3d on;
axis equal;
axis vis3d;
axis tight;
hold on;
xlabel('X'); ylabel('Y'); zlabel('Z');
% Plot all vectors
p1 = [0 0 0]';
for i=1:N
p2 = vs(:,i);
plot3ex(p1,p2);
end
% Trying to plot the limiting cone, but no success here :(
% k = [0 1];
% [X,Y,Z] = cylinder([0 1 0]');
% testsubject = surf(X,Y,Z);
% set(testsubject,'FaceAlpha',0.5)
% N = 50;
% r = linspace(0, 1, N);
% [X,Y,Z] = cylinder(r, N);
%
% h = surf(X, Y, Z);
%
% rotate(h, [1 1 0], 90);
plot3ex.m:
function p = plot3ex(varargin)
% Plots a line from each p1 to each p2.
% Inputs:
% p1 3xN
% p2 3xN
% args plot3 configuration string
% NOTE: p1 and p2 number of points can range from 1 to N
% but if the number of points are different, one must be 1!
% PVB 2016
p1 = varargin{1};
p2 = varargin{2};
extraArgs = varargin(3:end);
N1 = size(p1,2);
N2 = size(p2,2);
N = N1;
if N1 == 1 && N2 > 1
N = N2;
elseif N1 > 1 && N2 == 1
N = N1
elseif N1 ~= N2
error('if size(p1,2) ~= size(p1,2): size(p1,2) and/or size(p1,2) must be 1 !');
end
for i=1:N
i1 = i;
i2 = i;
if i > N1
i1 = N1;
end
if i > N2
i2 = N2;
end
x = [p1(1,i1) p2(1,i2)];
y = [p1(2,i1) p2(2,i2)];
z = [p1(3,i1) p2(3,i2)];
p = plot3(x,y,z,extraArgs{:});
end
Podany kod naprawdę nie ilustruje twojego pytania. Daj mi znać, jeśli podaję twój problem w prawidłowy sposób: masz ** _ określony _ ** stożkowy region (znany: _origin_, _direction_ i _departure angle_), i chcesz wygenerować losowy wektor (ten sam _origin_) z jego kierunkiem zawartym w stożkowa domena? – Hoki
Tak, dokładnie. Zaktualizowałem próbkę kodu. – Pedro77
Czy są jakieś wymagania dotyczące rozkładu kątów kosinusowych? Mogę myśleć, że kąty powinny być jednolite, ale twój kod wytwarza wektory, których kąty w stosunku do 'coneDir' są bardzo przekrzywione. –