2016-09-20 9 views
5

problemu:objętość Zapytanie o sztucznych bloków wewnątrz wypukłej

mam trójwymiarową chmurę punktów ciężkości każdego bloku reprezentującego blok. Dla uproszczenia ten przykład jest tylko dwuwymiarowy. Jak pokazano na rysunku, chcę uwzględnić bloki zainteresowania na podstawie parametru. W przypadku tutaj blok 1,6,5,4. Aby je dalej przetworzyć, muszę znaleźć najmniejszy kadłub wokół nich, używając albo kształtu alfa, albo wypukłego kadłuba. Mam współrzędne każdego ciężkości i wiem rozszerzenie bloku więc mogę łatwo znaleźć punkt krawędzi bloków przez:

xdimension=5; 
ydimension=5; 
block1=[5 15 1]; 
block2=[5 10 0]; 
block3=[5 5 0]; 
block4=[10 5 1]; 
block5=[10 10 1]; 
block6=[10 15 1]; 
block7=[15 5 0]; 
block8=[15 10 0]; 
block9=[15 15 0]; 
blocks=[block1;block2;block3;block4;block5;block6;block7;block8;block9] 

dimension=[xdimension/2 ydimension/2]; 
point1=[1 1].*dimension; 
point2=[1 -1].*dimension; 
point3=[-1 1].*dimension; 
point4=[-1 -1].*dimension; 
i=size(blocks,1); 
point1=repmat(point1,i,1); 
point2=repmat(point2,i,1); 
point3=repmat(point3,i,1); 
point4=repmat(point4,i,1); 
edges1=[blocks(:,1:2)+point1, blocks(:,3)] ; 
edges2=[blocks(:,1:2)+point2, blocks(:,3)]; 
edges3=[blocks(:,1:2)+point3, blocks(:,3)]; 
edges4=[blocks(:,1:2)+point4, blocks(:,3)]; 
edges=[edges1;edges2;edges3;edges4]; 
x=edges(edges(:,3)==1,1); 
y=edges(edges(:,3)==1,2); 
K=convhull(x,y) 
scatter(edges(:,1), edges(:,2)) 
hold on 
plot(x(K),y(K),'r-') 
hold off 

To daje obraz podobny do tego tutaj.

Pytanie

Jak mogę kwerendy powierzchnię (lub w moim prawdziwym problemem głośność), który jest dołączony przez wypukłej bloku 2 i 3? Potrzebuję dokładnej powierzchni/objętości każdego bloku , niezależnie od tych, które określam jako znajdujące się w tym miejscu (tutaj ze wskaźnikiem binarnym). Należy zauważyć, że jest to przykład i szukam pomysłów, jak to zrobić niezależnie od przykładu. Naprawdę byłbym wdzięczny za pomoc, bo ja tu utknąłem i nie mam pojęcia, jak sobie z tym poradzić.

enter image description here

Odpowiedz

0

Jeśli są skuteczne w znalezieniu kadłub covex (używając funkcji convhull), jego zmienna drugie wyjście da ci to, czego potrzebujesz (?).

[IDs,V] = convhull(X,Y,Z) 

Tutaj V objętość zamknięty w wypukłej punktów (X,Y,Z). Błogosław Matlab!

+1

mi wiadomo, jest to, chcę znać dokładną kwotę zawartą z 2 i 3 indywidualnie, a nie całkowitą objętość. ;) – KiW

1

w 2D Chciałbym użyć funkcji inpolygon aby sprawdzić, czy punkt znajduje się wewnątrz skrzyżowania wypukłej Hull i kwadratów 2 i 3.

na 3D nie znaleziono odpowiednika w MATLAB ale następujący matlab exchange file powinno być rozwiązaniem.

Przykładem sposobu korzystania z inhull funkcyjny, aby znaleźć punkty obszarów wewnątrz:

% Create a 3D cube 
cubePoints = randi(5,[500,3]); 

% Bounding volume 
boundingVolume = zeros(8,3); 
boundingVolume(1,:) = [1,3,1]; 
boundingVolume(2,:) = [1,3,3]; 
boundingVolume(3,:) = [3,3,1]; 
boundingVolume(4,:) = [3,3,3]; 
boundingVolume(5,:) = [3,1,3]; 
boundingVolume(6,:) = [3,1,1]; 
boundingVolume(7,:) = [2,1,1]; 
boundingVolume(8,:) = [2,1,3]; 

% Find points inside area 
inVol = inhull(cubePoints,boundingVolume); 

% Plot the point in the bounding volume in blue and the points outsode the 
% bounding volume in red 
scatter3(cubePoints(:,1).*inVol,cubePoints(:,2).*inVol,cubePoints(:,3).*inVol,36,'blue'); 
hold on 
scatter3(cubePoints(:,1).*~inVol,cubePoints(:,2).*~inVol,cubePoints(:,3).*~inVol,36,'red'); 
+0

To dobry początek, ale na podstawie punktów, jak można dokładnie uzyskać powierzchnię/objętość zawartych bloków? Używanie pojedynczych punktów brzegowych byłoby przybliżeniem, ale w zależności od rozmiaru kadłuba dość niedokładne. – KiW

+1

Chociaż może to teoretycznie odpowiedzieć na pytanie, [byłoby to lepsze] (// meta.stackoverflow.com/q/8259) do włączenia istotne części odpowiedzi tutaj, i podać link odniesienia. – Adriaan

0

Wierzę, że ta metoda działa, ale jeśli system jest duża, pod względem zużycia pamięci nie ma nic aby pochwalić się:

Najpierw skonstruuj cały wypukły kadłub w postaci 3d binarnej tablicy. Ponadto, każdy blok powinien tworzyć 3d binarną tablicę na całej przestrzeni, z elementami true w przedłużeniu bloku i false gdzie indziej. (Aby to zrobić, sprawdź link w Amitay's answer.)

Teraz możesz obliczyć udział każdego bloku z niego.Jeśli utworzona wszystko jak wyjaśniono, reszta jest prosta: można bezpośrednio liczyć nakładania na conv z każdym block następująco:

num = numel(block); 
shareofblock = zeros(num, 1); 
for jj = 1:num 
    overlap = block(jj) & conv; 
    shareofblock(jj) = sum(overlap(:)); 
end