Как рассчитать трехмерный центроид? - PullRequest
8 голосов
/ 28 января 2011

Есть ли вообще такая вещь, как трехмерный центроид? Позвольте мне быть предельно ясным - последние два дня я читал и читал о центроидах как на этом сайте, так и в Интернете, поэтому я прекрасно осведомлен о существующих сообщениях по этой теме, включая Википедия .

Тем не менее, позвольте мне объяснить, что я пытаюсь сделать. По сути, я хочу взять выбор ребер и / или вершин, но НЕ граней. Затем я хочу поместить объект в трехмерное положение центроида.

Я скажу тебе, чего не хочу:

  • Среднее число вершин, которое слишком сильно тянет в любом направлении с более детализированной сеткой.
  • Ограничивающий прямоугольник, потому что у меня уже есть кое-что для этого сценария.

Я открыт для предложений относительно центра масс, но я не понимаю, как это будет работать, потому что только вершины или ребра не определяют какую-либо массу, особенно когда я просто выбрал петлю ребра.

Для пинка я покажу вам PyMEL , над которым я работал, используя @ код Эмиля в качестве ссылки, но я не думаю, что это работает так, как должно:

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)

Ответы [ 4 ]

8 голосов
/ 28 января 2011

Теоретически centroid = SUM(pos*volume)/SUM(volume), когда вы разделяете деталь на конечные объемы, каждый из которых имеет местоположение pos и значение объема volume.

Это именно тот расчет, который делается для нахождения центра тяжестисоставная часть.

3 голосов
/ 28 января 2011

Существует не просто трехмерный центроид, это n-мерный центроид, и формула для него приведена в разделе «По интегральной формуле» цитируемой вами статьи Википедии.

Возможно, у вас проблемы с настройкой этого интеграла? Вы не определили свою форму.

[Редактировать] Я дополню этот ответ в ответ на ваш комментарий. Поскольку вы описали свою форму в терминах ребер и вершин, я буду считать, что это многогранник . Вы можете разбить многогранник на пирамиды, найти центроиды пирамид, а затем центроид вашей фигуры будет центроидом центроидов (этот последний расчет выполняется по формуле ja72).

Я предполагаю, что ваша форма выпуклая (без полых частей - если это не так, разбейте ее на выпуклые куски). Вы можете разделить его на пирамиды (триангулировать), выбрав точку во внутренней части и нарисовав края к вершинам. Тогда каждое лицо вашей фигуры - это основание пирамиды. Существуют формулы для центроида пирамиды (вы можете посмотреть это вверх, это 1/4 пути от центроида лица к вашей внутренней точке). Тогда, как было сказано, центроид вашей фигуры - это центроид центроидов - конечный расчет ja72, а не интеграл - как указано в другом ответе.

Это тот же алгоритм, что и в ответе Хью Ботвелла, однако я считаю, что 1/4 является верным, а не 1/3. Возможно, вы можете найти какой-то код для этого где-то где-то, используя условия поиска в этом описании.

2 голосов
/ 28 января 2011

Мне нравится вопрос. Центр масс звучит правильно, но возникает вопрос, какая масса для каждой вершины?

Почему бы не использовать среднюю длину каждого ребра, включающего вершину? Это должно хорошо компенсировать области с плотной сеткой.

1 голос
/ 28 января 2011

Вам придется воссоздать информацию о лице из вершин (по сути, триангуляцию Делоне).

Если ваши вершины определяют выпуклую оболочку, вы можете выбрать любую произвольную точку A внутри объекта. Рассматривайте свой объект как коллекцию пирамидальных призм, имеющих вершину А и каждое лицо в качестве основы.

Для каждого лица найдите область Fa и 2-й центр тяжести Fc; тогда масса призмы пропорциональна объему (== 1/3 основания * высоты (компонент Fc-A перпендикулярно лицу)), и вы можете игнорировать постоянную пропорциональности, если вы делаете то же самое для всех призм; центр масс (2/3 A + 1/3 Fc) или треть пути от вершины до 2-го центроида основания.

Затем можно сделать средневзвешенное значение точек центра масс, чтобы найти трехмерный центроид объекта в целом.

Тот же самый процесс должен работать для невыпуклых оболочек - или даже для A вне корпуса - но вычисление лица может быть проблемой; вам нужно быть осторожным с руками на ваших лицах.

...