2011-01-28 13 views
6

Czy istnieje nawet coś takiego jak centroid 3D? Pozwól, że będę całkowicie czysty - czytałem i czytałem o centroidach przez ostatnie 2 dni zarówno na tej stronie, jak i w Internecie, więc doskonale zdaję sobie sprawę z istniejących postów na ten temat, w tym z Wikipedia.Jak obliczyć centroid 3D?

Powiedziawszy to, pozwól mi wyjaśnić, co próbuję zrobić. Zasadniczo chcę wybrać krawędzie i/lub wierzchołki, ale NIE twarze. Następnie chcę umieścić obiekt w pozycji środka ciężkości 3D.

powiem ci, czego nie chcą:

  • Wierzchołki Średnio co ciągnąć zbyt daleko w dowolnym kierunku, który ma bardziej szczegółowe wysokiej siatki.
  • Środek obwiedni, ponieważ mam już coś na ten scenariusz.

Jestem otwarty na sugestie dotyczące środka masy, ale nie widzę jak to będzie działać, ponieważ krawędzie lub wierzchołki sam nie określają jakichkolwiek masowych, zwłaszcza gdy mam tylko pętlę krawędzi wybrany.

dla zabawy, to ci pokażę niektóre PyMEL, że pracował w górę, używając @Emile's code jako punkt odniesienia, ale nie sądzę, że to działa tak, jak powinien:

from pymel.core import ls, spaceLocator 
from pymel.core.datatypes import Vector 
from pymel.core.nodetypes import NurbsCurve 

def get_centroid(node): 
    if not isinstance(node, NurbsCurve): 
     raise TypeError("Requires NurbsCurve.") 
    centroid = Vector(0, 0, 0) 
    signed_area = 0.0 
    cvs = node.getCVs(space='world') 
    v0 = cvs[len(cvs) - 1] 
    for i, cv in enumerate(cvs[:-1]): 
     v1 = cv 
     a = v0.x * v1.y - v1.x * v0.y 
     signed_area += a 
     centroid += sum([v0, v1]) * a 
     v0 = v1 
    signed_area *= 0.5 
    centroid /= 6 * signed_area 
    return centroid 

texas = ls(selection=True)[0] 
centroid = get_centroid(texas) 
print(centroid) 
spaceLocator(position=centroid) 

Odpowiedz

8

W teorii centroid = SUM(pos*volume)/SUM(volume) po podzieleniu części na skończone woluminy, każda z lokalizacją pos i wartością objętości volume.

To jest dokładnie obliczenie wykonane dla znalezienia środka ciężkości części złożonej.

+0

Mam zamiar zaakceptować tę odpowiedź dla uproszczenia, ale nie będę w stanie przetestować jej do końca. Będę was informować. – jedmao

2

podoba mi się pytanie. Środek masy brzmi dobrze, ale pojawia się pytanie, jaka masa dla każdego wierzchołka?

Dlaczego nie użyć średniej długości każdej krawędzi zawierającej wierzchołek? To powinno zrekompensować ładnie obszary gęstą siatką.

+0

Wiesz, po prostu myślałem to samo kilka minut, zanim to opublikowałeś. Zastanawiam się, jaki byłby rezultat. Ponieważ matematyka byłaby w tym przypadku bardzo prosta, ponieważ byłaby to średnia ważona. Muszę teraz spać, ale zagłębię się w to jutro. – jedmao

+0

Nadal pracuję nad tym rozwiązaniem. Postaram się Cię zaktualizować. – jedmao

+0

Będę zainteresowany, aby zobaczyć wynik. Będzie to wyraźnie działać dla niektórych prostych przypadków testowych. Na przykład. Cylinder z wieloma wierzchołkami definiującymi jeden koniec i mniej na drugim. Jeśli to nie działa, jakie przypadki testowe są problemem? – Keith

3

Istnieje nie tylko centroid 3D, istnieje n-wymiarowy środek ciężkości, a wzór dla niego jest podany w sekcji "Przez integralną formułę" artykułu z Wikipedii, który cytujesz.

Być może masz problem z ustawieniem tej całki? Nie zdefiniowałeś swojego kształtu.

[Edytuj] Podtrzymam tę odpowiedź w odpowiedzi na Twój komentarz. Ponieważ opisałeś swój kształt pod względem krawędzi i wierzchołków, zakładam, że jest to polyhedron. Możesz podzielić poliedron na piramidy, znaleźć centroidy piramid, a następnie centroid twojego kształtu jest centroidem centroidów (to ostatnie obliczenie odbywa się za pomocą wzoru ja72).

Założę się, że twój kształt jest wypukły (brak pustych części - jeśli tak nie jest, przełóż go na wypukłe kawałki). Możesz podzielić go na piramidy (triangulować je), wybierając punkt we wnętrzu i rysując krawędzie do wierzchołków. Wtedy każda twarz twojego kształtu jest podstawą piramidy. Istnieją formuły dla środka ciężkości piramidy (możesz to sprawdzić, to 1/4 drogi od środka ciężkości twarzy do twojego wnętrza). Następnie, jak już powiedziano, centroid twojego kształtu jest centroidem centroidów --- skończone obliczenia ja72, a nie całka - jak podano w innej odpowiedzi.

To jest ten sam algorytm co w odpowiedzi Hugh Bothwell, jednak uważam, że 1/4 jest poprawna zamiast 1/3. Być może znajdziesz jakiś kod, czai się gdzieś przy użyciu wyszukiwanych terminów w tym opisie.

+0

Tak, cóż ... żenująco, nie wiem nawet, czym jest całka. Zgubiłem się, gdy nie widzę rzeczywistego kodu. Nie rozumiem formuł. I masz rację. Mój kształt niekoniecznie jest zdefiniowany, gdy mam kolekcję wierzchołków. Jak możesz poprawnie podłączyć kropki? – jedmao

1

Będziesz musiał odtworzyć informacje o powierzchni z wierzchołków (w zasadzie triangulacja Delauneya).

Jeśli Twoje wierzchołki definiują wypukły kadłub, możesz wybrać dowolny punkt A wewnątrz obiektu. Traktuj swój obiekt jako zbiór ostrosłupowych pryzmatów mających wierzchołek A i każdą powierzchnię jako podstawę.

Dla każdej twarzy znajdź obszar Fa i 2-centroid Fc; następnie masa pryzmatu jest proporcjonalna do objętości (= 1/3 podstawy * wysokości (składowa Fc-A prostopadła do twarzy)) i można zignorować stałą proporcjonalności, o ile robimy to samo dla wszystkich pryzmatów; środek masy to (2/3 A + 1/3 Fc), czyli jedna trzecia drogi od wierzchołka do centroidu 2d podstawy.

Następnie można zrobić średnią masę punktów środka masy, aby znaleźć centroid 3d obiektu jako całości.

Ten sam proces, , powinien zadziałać dla kadłubów nie wypukłych - lub nawet dla A poza kadłubem - ale obliczenie twarzy może być problemem; musisz uważać na pochwałę twoich twarzy.

+0

Próbowałem wykorzystać jakiś kod Delauney, który znalazłem (i uproszczono), aby to działało, ale nie jestem w 100% pewien, czy działa poprawnie. Niestety nie mogę na tym polegać na numpy. Nadal pracuję nad tym rozwiązaniem. Będę Cie informować na bieżąco. – jedmao