Покомпонентный алгоритм просмотра для CAD

Я делаю программу для просмотра 3D-моделей САПР и хотел бы построить автоматизированные разнесенные виды. Все узлы, которые будут рассматриваться, являются аксиально-симметричными. Некоторые могут не быть, но большинство из них. Я хотел бы вычислить алгоритм автоматического перемещения деталей в сборке в покомпонентную позицию представления. Вот пример того, чего я хочу достичь с помощью алгоритма (за вычетом ярлыков):

Покомпонентное представление

Единственное значение, с которым я должен работать, - это центр ограничивающей рамки каждой части. Если требуется больше информации, я могу рассчитать больше информации, но, похоже, ее должно быть достаточно. Грубый подход, который я имею в виду, состоит в том, чтобы вычислить вектор от начала сборки до центра каждой части вдоль оси аксиально-симметричной оси, а затем вычислить радиальный вектор по центру части относительно центральной оси. Оттуда мне нужно было бы вычислить некоторые вычисления, которые могли бы масштабировать положение каждой части вдоль некоторой комбинации этих двух векторов. Это часть, где я не совсем уверен, в каком направлении идти с этим. Изображение, которое я включил, показывает точную функциональность, которую я хотел бы, но я хочу, чтобы иметь возможность масштабировать позицию с помощью любого значения с плавающей точкой, чтобы развернуть или скомпентировать покомпонентное представление, причем 1.0 является исходной собранной моделью. Любые идеи?

Ответ 1

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

Чтобы проиллюстрировать их примером, я буду использовать следующие числа (ограничивающие прямоугольники вдоль оси, всего пять частей):

P1: [ 0,10] (battery)
P2: [10,14] (motor)
P3: [14,16] (cog)
P4: [16,24] (bit holder)
P5: [18,26] (gear casing)

В то время как части P1 до P4 точно касаются друг друга, P4 и P5 фактически перекрываются.

Первый - это алгоритм, который в основном масштабирует расстояния на коэффициент, например, вы предложили. Это будет страдать, если размер кусков в сборке сильно отличается, но также и для перекрывающихся частей (например, в вашем примере вдоль оси расширение круга cog намного меньше, чем бит-держатель).

Пусть коэффициент масштабирования f, тогда центр каждого ограничивающего блока масштабируется f, но расширение не является. Затем части будут

P1:  5 + [-5,5]   => P1':  5*f + [-5,5]
P2: 12 + [-2,2]   => P2': 12*f + [-2,2]
P3: 15 + [-1,1]   => P3': 15*f + [-1,1]
P4: 20 + [-4,4]   => P4': 20*f + [-4,4]
P5: 22 + [-4,4]   => P5': 22*f + [-4,4]

Расстояние между частями P1' до P4 затем определяется выражением

P2' - P1' : (12*f-2) - (5*f+5) = 7*(f-1)
P3' - P2' : (15*f-1) - (12*f+2) = 3*(f-1)
P4' - P3' : (20*f-4) - (15*f+1) = 5*(f-5)

Как и ожидалось, разность равна нулю для f=0, но для любого разобранного вида расстояние сильно зависит от размеров отдельных частей. Я не думаю, что это будет выглядеть слишком хорошо, если изменение размеров будет больше.

Дополнительно для перекрывающихся частей

P5' - P4' : (22*f-4) - (20*f+4) = 2*f-8

они все еще перекрываются для разумного f.

Другая возможность заключалась бы в определении не масштабного коэффициента для оси, а постоянной частичной дистанции d. Затем ограничивающие прямоугольники будут выровнены следующим образом:

P1': [ 0,10]
P2': [10,14]+d
P3': [14,16]+2*d
P4': [16,24]+3*d
P5': [18,26]+4*d+6

Обратите внимание, что в последней строке мы добавили 24-8=6, то есть перекрытие, чтобы дифференцировать две части.

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

Одна из возможностей состоит в том, чтобы сгруппировать части в группы на первом шаге, а затем применить алгоритм к ограничивающей рамке этих групп. Впоследствии его можно снова применить к частям в каждой группе, опуская части, которые охватывают более одной подгруппы. В вашем случае это будет (можно отметить вложенную группировку):

[
    ([battery,(switch,circuit switch),motor],handle top),
    motor cog, 
    tri-cog,
    red-cog,
    circle-cog,
    bit-holder,
    (gear casing,spring,lock knob)
]

Возможно, вы заметили, что я ввел две разные группы: части/группы в квадратных скобках обрабатываются алгоритмом, т.е. между каждой частью/подгруппой внутри такой группы добавляется интервал, тогда как группы внутри круглых фигурных скобок не взорвался.

До сих пор мы не обрабатывали радиальный взрыв, потому что он прекрасно отделяется от обработки оси. Но опять же оба подхода могут быть использованы и для радиального взрыва. Но опять же, на мой взгляд, второй алгоритм дает более приятные результаты. Например. для радиальной обработки группы можно сделать следующим образом:

 [
     (battery,switch,<many parts>,gear casing),
     (switch,spring),
     (handle top, lock knob)
 ]

В этом случае мы добавили бы дополнительную компоненту r ко всем радиальным центрам во второй группе и 2*r ко всем в третьей группе.

Обратите внимание, что простой алгоритм масштабирования выполняется без специального указания пользователя (после того, как задан масштабный коэффициент), в то время как второй использует дополнительную информацию (группировку).

Надеюсь, это довольно длинное объяснение даст вам несколько идей о том, как продвигаться дальше. Если мои объяснения в какой-то момент неясны или у вас есть дополнительные вопросы, не стесняйтесь комментировать.