Verfasst am: 06.09.2017, 17:43
Titel: Kugeln versch. Größen in 3D-Raum möglichst eng anordnen
Moin zusammen,
ich versuche einen 3D-Sedimentlayer aus verschiedenen Kugelgrößen zu erstellen. Die Packungsdichte für die definierten Kugeln soll möglichst eng sein. Ich benötige jeweils "nur" die Koordinaten der Kugelmitten um diese in eine .xml zu schreiben und dort .stl-Dateien mit definierten Größen an das eigentliche Programm zu übergeben.
Mein Ansatz ist, dass ich für den zu füllenden Raum eine Raummatrix =ones(x,y,z) und für jede Kugel i mit Radius R_i zunächst eine Kugelmatrix_i =ones (R_i, R_i, R_i) erstelle. In alle von der Kugel belegten Felder der Kugelmatrix werden Nullen geschrieben. Wird eine Kugel gelegt, sollen an entsprechender Stelle in der Raummatrix auch Nullen geschrieben werden.
Hierzu gehe ich jeden Eintrag der Raummatrix ab und wenn ein Eintrag 1 ist soll geprüft werden, für welche Kugeln Platz vorhanden ist. Wenn ich bspw. an der Stelle (x,y,z) bin soll die Kugel um den Punkt (x+Radius y+Radius, z+Radius) gezeichnet bzw. natürlich auch entsprechend der Platz überprüft werden.
Das Gitter ist durch den kleinsten Kugeldurchmesser definiert, sodass am Ende jede Zelle ausgefüllt sein sollte.
Mein Problem:
Wie kann ich aus der Raummatrix herauslesen, welche Kugel gelegt werden kann und wie schreibe ich die Info in die Raummatrix. Ein Abgleich der gesamten Kugelmatrix mit der Raummatrix ist zu unpräzise, da ja lediglich der tatsächlich durch die Kugel belegte Raum (Nullen der Kugelmatrix) frei sein muss / überschrieben werden muss.
Ich Stelle mir eine Abfrage vor, mit der ich den Ort der Einträge "0" erhalte und diese dann in der Raummatrix prüfe bzw. überschreibe. Im Sinne von:
--> finde für jede Kugel: Einträge Kugelmatrix == 0 (bräuchte quasi für jede Schicht in Z die Anzahl der Schritte bis zur ersten Null jeder Zeile und dann die Anzahl der Nullen der Zeile.)
--> Prüfe ob entsprechende Orte der Raummatrix ==1 (-->Orte könnten sowas sein wie "x + Weg bis zur 0 : x +Weg bis ende der Nullen" für alle y und z ; liefert mögliche Kugelgrößen )
--> Wähle zufällig aus möglichen Kugelgrößen eine aus
--> Schreibe an entsprechende Stellen der Raummatrix 0
Da sich unter meiner "Kurzbeschreibung" wahrscheinlich keiner etwas vorstellen kann, habe ich exemplarisch für eine Kugel mal den Code spendiert und eine Raummatrix dazu, sodass hoffentlich zumindest verständlich wird, was mit "Kugelmatrix" und "Raummatrix" gemeint ist und das ganze etwas anschaulicher wird.
Raummatrix = ones(5*D3,3*D3,2*D3);
%% Berechnung der Radien der einzelnen Kugelsegmente für Inof über Z
% Berechnung des ersten Eintrags: Abhängig von Position des Randes in der % Zelle --> 1. Viertel, 2. und 3. Viertel, 4. Viertel ifmod(R3,1) > 0 && mod(R3,1) < 0.25
r3 (1) = sqrt(R3^2-(R3-mod(R3,0.5))^2); %Messung am Rand der Zelle
elseifmod(R3,1) >= 0.25 && mod(R3,1) <= 0.75
r3 (1) = sqrt(R3^2-(R3-(0.25*D_min))^2); %Messung bei R-0,25*D_min --> 0,25: Rand bis 0,75 Mitte
else
r3 (1) = sqrt(R3^2-(R3-(R_min))^2); %Messung in Zellmitte, wenn die Höhe der Zelle zu min. 75% bedeckt end
% Berechnung der übrigen Radien jeweils in Zellmitte mit D_min als % Schrittweite for i = 2 : ceil(R3)
r3 (i) = sqrt(R3^2-(R3 - mod(R3,1)-(R_min+(i-2)*D_min))^2); %R3 auf ganze Zahl reduzieren und -R_min errechnet Wert in Zellmitte
end
a=1;
for i = ceil(R3)+1 : ceil(R3) *2
r3(i) = r3(i-a);
a = a+2;
end
%% Berechnung der Radien jedes Kreissegments in der Fläche und schreiben aller Infos in die Kugelmatrix
ifmod(R2,1) > 0 && mod(R2,1) < 0.25
r2 (1) = sqrt(R2^2-(R2-mod(R2,0.5))^2); %Messung am Rand der Zelle
elseifmod(R2,1) >= 0.25 && mod(R2,1) <= 0.75
r2 (1) = sqrt(R2^2-(R2-(0.25*D_min))^2); %Messung bei R-0,25*D_min --> 0,25: Rand bis 0,75 Mitte
else
r2 (1) = sqrt(R2^2-(R2-(R_min))^2); %Messung in Zellmitte, wenn die Höhe der Zelle zu min. 75% bedeckt end
% Berechnung der übrigen Radien jeweils in Zellmitte mit D_min als % Schrittweite for i = 2 : ceil(R2)
r2 (i) = sqrt(R2^2-(R2 - mod(R2,1)-(R_min+(i-2)*D_min))^2); %R2 auf ganze Zahl reduzieren und -R_min errechnet Wert in Zellmitte
end
a=1;
for i = ceil(R2)+1 : ceil(R2) *2
r2(i) = r2(i-a);
a = a+2;
end
%Schreiben der Kugelmatrix
for n = 1 : ceil(D2) + mod(ceil(D2),2)
r = r2 (n); %Entsprechender Radius
j = ceil(R3)-floor(R2)+n-1; %in jeweilige Zeile
Kugelmatrix (j , ceil(R3) - floor(r) : ceil(R3) + ceil(r), h) = 0;
Kugelmatrix (: , :, D4+1-h) = Kugelmatrix (: , :, h); %Ausnutzen der Spiegelsymmetrie
end end
%Schritt 1: prüfen welche Kugel passt Radien = (0.5 : 0.5 : 6)
%Schritt 2: Random-Abfrage aus passenden Kugeln
%Schritt 3: Schreiben der Kugel in die Raummatrix
Die teils aufwendige Berechnung der ersten Zeile der Radien ist in den unterschiedlichen Kugelgrößen begründet.
Falls jemand eine bessere Idee hat, um Kugeln (bzw. später auch ellipsenartige Körper) im Raum anzuordnen, bin ich offen für Vorschläge. Zu beachten ist aber, dass meine Matlab-Kenntnisse eher rudimentärer Art sind und die Rechenzeit nicht ganz so wichtig ist, da sich die anschließende Simulation im Bereich von Tagen oder Wochen bewegen wird
In diesem Sinne viel Spaß beim Knobeln und vielen Dank im Voraus!
aufmerksam geworden, mit dem sich das ganze Problem vllt. besser lösen lässt. Insbesondere, da die Kugeln später zu Steinen / Sandkörnern werden sollen.
Daher ist für mich das Thema gelöst.
Dennoch danke
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.