image

Одна из самых труднорешаемых задач в системах автоматизированного проектирования – скругления при моделировании объектов сложных форм. За построение скруглений, как и за всю геометрию в САПР, отвечает геометрическое ядро.

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

В чем его сложность и как работает алгоритм, рассказывает Анна Ладилова, математик-программист C3D Labs.

Что такое «полное скругление»


Допустим, у нас есть тело с тремя цепочками граней – центральной (верхней) и боковыми (правой и левой). Требуется заменить центральную грань поверхностью скругления, которая бы гладко стыковалась с соседними боковыми гранями. Эта новая поверхность и будет полным скруглением. В общем случае она имеет переменный радиус, определяемый автоматически.

image

Во многих известных CAD-системах операция полного скругления (full-round fillet) реализована, но ее математика не раскрывается.

image
Операция Full round fillet в Solidworks

Поэтому мы разработали собственный алгоритм. И он отличается от алгоритмов других разработчиков.

Операции, хотя и называются одинаково, но приводят к немного разным результатам. Это говорит о том, что в SolidWorks скруглению трех граней дается другое определение.

image
Справа — исходная модель, в центре полное скругление в SolidWorks, слева — в C3D.

Алгоритм построения полного скругления


Задача построения любого вида скруглений включает в себя несколько этапов:

  1. Разбить заданную цепочку на элементарные составляющие (для скругления трех граней это ровно три грани: левая, правая и центральная).
  2. Последовательно упорядочить элементарные составляющие.
  3. Построить поверхность скругления для каждой элементарной составляющей.
  4. «Сшить» ребрами соседние поверхности скругления.
  5. Обработать торцевые участки цепочки скруглений, т. е. корректно соединить их с модифицируемым телом.

Ключевым моментом в этой процедуре является третий шаг: построить поверхность скругления для трех заданных граней.

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

Рассмотрим, как можно вычислить тройку точек – по одной на каждом сплайне.

image
Обработка элементарной составляющей. Скругление касается каждой из трех граней по кривым l0; l1; l2. Синей линией изображено поперечное сечение

В каждом поперечном сечении $ABC$:

  • $OA = OB = OC$ – рассчитывается автоматически
  • $OA, OB, OC$ ортогональны касательным плоскостям поверхностей в соответствующих точках
  • $p$0 – точка привязки, лежит в плоскости $ABC$.

image

Определим исходные поверхности центральной, левой и правой граней радиус-векторами в некоторой области определения. Пусть боковые поверхности задаются радиус-векторами $r$1$(u, v)$ и $r$2$(z, w)$, а центральная – $r$0$(x, y)$. Введем положительный числовой параметр $d$.

Обозначим через $n$0$(x, y)$, $n$1$(u, v)$, $n$2$(z, w)$ единичные нормали к соответствующим поверхностям, направленные «внутрь».

image
Поперечное «сечение» при построении скругления

Потребуем, чтобы концы этих нормалей, растянутых в $d$ раз, попали в одну точку – точку $O$.

В терминах дифференциальной геометрии наши требования можно сформулировать системой из семи уравнений с семью параметрами:

$dn$0$(x, y)$ = $dn$1$(u, v)$,
$dn$0$(x, y)$ = $dn$2$(z, w)$,
($r$0$(x, y)$$p$0, $r$1$(u, v)$$p$0, $r$2$(z, w)$$p$0) = $0$,

где

  • $d$ — переменный радиус
  • $p$0 — точка привязки
  • $x, y, u, v, z, w$ — переменные из области определения параметров.

Используя алгоритмы численных методов (например, метод Ньютона), мы находим решение этой системы: $x$0, $y$0, $u$0, $v$0, $z$0, $w$0, $d$0.

Решение определяет точки касания с поверхностями:

  • $r$0($x$0, $y$0),
  • $r$1($u$0, $v$0),
  • $r$2($z$0, $w$0),

а также радиус $d$0.

Пробегая некоторый набор точек $p$0, мы получаем наборы троек точек касания с поверхностями, по которым можно восстановить «кривые касания» $l$0, $l$1, $l$2 как сплайны Эрмита, проходящие через рассчитанные точки.

Область определения [$t$min, $t$max] у всех кривых одна и та же, причем параметру $t$i соответствуют точки $r$0i, $r$1i, $r$2i. Далее по этим кривым производится расчет нужного сечения скругления.

Зафиксируем некоторый параметр $t$ и вычислим для него точки:

  • $r$0$(x(t), y(t)),$
  • $r$1$(u(t), v(t)),$
  • $r$2$(z(t), w(t)) $.

Построим сплайновую кривую, проходящую через эти точки и ортогональную в них векторам нормали $n$0$(x(t), y(t))$, $n$1$(u(t), v(t))$, $n$2$(z(t), w(t))$ соответственно.

Если слегка изменить постановку задачи и искать кривую по заданным точкам и касательным векторам в этих точках, то методы, которыми можно реализовать такой сплайн, можно найти, например, в книге Николая Голованова «Геометрическое моделирование».

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

Итак, для каждого параметра $t$ мы можем определить набор точек для построения NURBS, а следовательно, определить каждую точку поперечного сечения поверхности скругления. Таким образом, задача построения поверхности полностью решена.

В описании этой части алгоритма остался небольшой вопрос — как «правильно» выбрать набор точек $p$0, соответствующих поперечному сечению, по которым можно будет легко восстановить «кривые касания» $l$0, $l$1, $l$2?

Представляется разумным брать их с некоторой заранее выбранной кривой. В детали построения этой кривой мы вдаваться не будем, отметим только, что она должна быть гладкой, без самопересечений и «усреднять» цепочки ребер, ограничивающих слева и справа центральную грань.

image
Слева поперечные сечения, зависящие от точки $p$0.
Справа фигуры могут быть достаточно сложными, поэтому правильно выбрать «вспомогательную» кривую — это отдельная задача.


Теперь, когда мы умеем строить поверхности скругления для простейших элементарных случаев, можно перейти к более сложной задаче: построить поверхность для цепочки граней.
Здесь основная проблема — «сшить» соседние поверхности гладким образом. Это четвертый шаг алгоритма.

Трудность заключается именно в гладкости сшивки, поскольку поверхности построены при разных начальных данных. Чтобы обеспечить гладкость, приходится прибегать к различным ухищрениям: менять направление и длину векторов производных в продольном направлении на некотором расстоянии от границы, менять значения производных весовых функций на границах и т.д. Результаты видны на рисунке: более гладкие линии «зебры» соответствуют более гладкой поверхности.

image

image
Вверху модель без алгоритма сглаживания. Внизу — после применения алгоритма.

Итог


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


Автор — Анна Ладилова, к.ф.-м.н., математик-программист C3D Labs

Комментарии (5)


  1. Newm
    07.11.2019 14:12

    Нескромный вопрос… Есть ли что-то подобное для openscad?


  1. Rikhmayer
    08.11.2019 13:57

    После фразы

    В терминах дифференциальной геометрии наши требования можно сформулировать системой из семи уравнений с семью параметрами

    В третьем уравнении явно лишняя скобка. И там же все стало окончательно непонятно :)
    Как там получается 7 уравнений (я правильно понимаю, все, что через запятую = О)? И какой смысл у точки привязки?


    1. ladilova
      09.11.2019 15:16
      +1

      В первом и втором уравнениях ni и ri — это векторы в пространстве.
      Если задано уравнение x = a, где x=(x1,x2,x3) и a =(a1,a2,a3), то оно эквивалентно системе из трех линейных («обычных») уравнений:
      x1=a1,
      x2=a2,
      x3=a3.
      Таким образом, первые 2 строчки системы дают 6 уравнений, а последнее — седьмое.

      В последнем уравнении слева — смешанное произведение трех векторов, которое приравнивается к 0.


      1. Rikhmayer
        09.11.2019 15:19

        Ага, со скобкой понятнее, спасибо


    1. ladilova
      09.11.2019 15:41
      +1

      Последнее уравнение утверждает, что точка p0 лежит в плоскости, определенной точками r0(x,y), r1(u,v) и r2(z,w). Без этого условия (соответственно, без этого уравнения) система будет иметь бесконечное (однопараметрическое) семейство решений. Точка «привязки» p0 как раз выступает в роли параметра.