Алгоритм покомпонентного представления для САПР

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

Вид в разобранном виде

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


person Davido    schedule 28.03.2011    source источник


Ответы (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 фактически перекрываются.

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

Пусть коэффициент масштабирования равен 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 ко всем центрам третьей группы.

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

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

person Howard    schedule 28.03.2011
comment
Ух ты. +1 за тщательность. Хотел бы я дать больше. - person Justin Morgan; 29.03.2011