Я бы начал с написания функции, которая создает случайные стержни:
function [rns,rne] = myrandom(domain,len,N)
rns = rand(N,3).*domain; % Start --> rns = bsxfun(@times,rand(N,3),domain)
rne = rand(N,3)-0.5; % End
% Unit Deltas
delta = zeros(N,1);
for k = 1:N
delta(k) = norm(rne(k,:));
end
% Length Deltas
rne = len*rne./delta; % --> rne = len*bsxfun(@rdivide,rne,delta)
% End Points
rne = rns + rne;
% remove rods the exceed the domain:
notValid = any(rne>domain,2); % --> notValid = any(bsxfun(@gt,rne,domain),2);
rns(notValid,:)=[];
rne(notValid,:)=[];
end
Эта функция получает domain
как [bx by bz]
, а также длину стержней как len
, и N
количество стержней для генерации.Обратите внимание, что с помощью поэлементного умножения (.*
) я исключил первый цикл for
.
Если вы используете версию MATLAB до 2016b, вам нужно использовать bsxfun
:
В MATLAB® R2016b и более поздних версиях встроенные двоичные функции, перечисленные в этой таблице, независимо поддерживают неявное расширение.
Затронутые строки помечены -->
в коде (с альтернативой).
Последние три строки в функции удаляют из результата все этапы, которые превышают размер домена (надеюсь, я правильно вас понял).
Далее явызовите эту функцию в скрипте:
% domain size
bx = 160;
by = 40;
bz = 40;
domain = [bx by bz];
lf = 12; % rod length
nf = 500; % Number of rods
[rns,rne] = myrandom(domain,lf,nf);
u = unique([rns rne],'rows');
remain = nf-size(u,1);
while remain>0
[rns_temp,rne_temp] = myrandom(domain,lf,remain);
rns = [rns;rns_temp];
rne = [rne;rne_temp];
u = unique([rns rne],'rows');
remain = nf-size(u,1);
end
После базовых определений вызывается функция и возвращает rne
и rns
, которые, вероятно, меньше, чем nf
.Затем мы проверяем дубликаты и сохраняем все уникальные стержни в u
.Мы вычисляем стержни, оставшиеся для вычисления, и используем цикл while
для генерации новых стержней по мере необходимости.На каждой итерации цикла мы добавляем вновь созданные стержни к тем, которые у нас есть в rne
и rns
, и проверяем, сколько уникальных векторов у нас сейчас, и, если их достаточно, мы покидаем цикл (тогда вы можете добавитьпечать в файл).
Обратите внимание, что:
Я не был уверен, что вы подразумеваете под ", в случае наложения создайте другое место для нового стержня« - хотите ли вы иметь больше nf
стержней, если некоторые являются дубликатами, то, из которых nf
уникальны (что делает код выше)?или вы хотите удалить дубликаты и остаться только с nf
уникальными стержнями?В случае последнего варианта я бы вставил функциональную часть unique
в функцию, которая создает стержни myrandom
.
Цикл Wile, как написано выше, неэффективен, так какпредварительное выделение памяти не выполняется.Я не уверен, что это возможно, если вы просто хотите создать больше стержней, но сохраните дубликаты, но если нет (второй вариант в 1 выше), и если вы собираетесь использовать это выделение, то предварительное распределение очень рекомендуется.