Как AutoCAD рассчитывает конечные касательные для шлицев, определяемых только точками подгонки? - PullRequest
6 голосов
/ 19 июня 2020

AutoCAD позволяет сохранять объекты СПЛАЙН в файлах DXF, определяемых только точками подгонки, проблема в том, что такое определение сплайна имеет бесконечные числовые правильные решения, а Autodesk не предоставляет необходимую информацию для расчета требуемых параметров на основе заданного подбора. точек.

tl; dr - Отсутствующая информация - это предполагаемые начальные и конечные касательные в направлении и величине для входных касательных к глобальной интерполяции B-сплайна с конечными производными, может ли кто-нибудь помочь вычислить эти значения?

Полный исходный код на github.

Я использую BricsCAD для тестирования, но «Trueview 2020» показывает те же результаты.

1. Сценарий

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

# First spline defined by control vertices interpolated from given fit points
s = global_bspline_interpolation(points, degree=3)
msp.add_spline(dxfattribs={'color': 4, 'layer': 'Global Interpolation'}).apply_construction_tool(s)
# Second spline defined only by fit points as reference
spline = msp.add_spline(points, degree=3, dxfattribs={'layer': 'BricsCAD B-spline', 'color': 2})
doc.saveas(DIR / 'fit-points-only.dxf')

Сплайн, интерполированный BricsCAD из подходящих точек, не соответствует сплайн, определяемый интерполированными управляющими вершинами:

Spline without constraints

2. Сценарий

Помимо точек подгонки, я также сохраняю значения начальной и конечной касательной в файле DXF. Интерполяция выполняется путем интерполяции глобальной кривой с конечными производными (Piegl & Tiller: "Книга NURBS" - глава 9.2.2).

Я выбрал произвольный угол (100 градусов) в качестве начальной и конечной касательных, величина касательной оценивается методом «Общая длина хорды».

m1, m2 = estimate_end_tangent_magnitude(points, method='chord')
start_tangent = Vector.from_deg_angle(100) * m1
end_tangent = Vector.from_deg_angle(-100) * m2
# First spline defined by control vertices interpolated from given fit points and end-tangents
s = global_bspline_interpolation(points, degree=3, tangents=(start_tangent, end_tangent))
msp.add_spline(dxfattribs={'color': 4, 'layer': 'Global Interpolation'}).apply_construction_tool(s)
# Result matches the BricsCAD interpolation if fit points, start- and end
# tangents are stored explicit in the DXF file.
# Second spline defined by fit points as reference
spline = msp.add_spline(points, degree=3, dxfattribs={'layer': 'BricsCAD B-spline', 'color': 2})
# set explicit start- and end tangent as unit vectors
spline.dxf.start_tangent = Vector.from_deg_angle(100)
spline.dxf.end_tangent = Vector.from_deg_angle(-100)
doc.saveas(DIR / 'fit-points-and-tangents.dxf')

Сплайн, интерполированный BricsCAD, теперь точно соответствует сплайну, заданному интерполированными контрольными вершинами:

matching splines

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

3. Сценарий

Мне нужны контрольные вершины для рендеринга B-сплайна, но начальные и конечные касательные не сохраняются в файле DXF, как в сценарии 1. Требуется оценка начальных и конечных касательных, лучший результат по : "5-точечная интерполяция" из "Книги NURBS", Piegl & Tiller

tangents = estimate_tangents(points, method='5-points')
# Estimated tangent angles: (108.43494882292201, -108.43494882292201) degree
m1, m2 = estimate_end_tangent_magnitude(points, method='chord')
start_tangent = tangents[0].normalize(m1)
end_tangent = tangents[-1].normalize(m2)
# First spline defined by control vertices interpolated from given fit points and end-tangents
s = global_bspline_interpolation(points, degree=3, tangents=(start_tangent, end_tangent))
msp.add_spline(dxfattribs={'color': 4, 'layer': 'Global Interpolation'}).apply_construction_tool(s)
# Second spline defined by fit points as reference, but without explicit start- and end 
# tangents to see if my estimations are correct.
msp.add_spline(points, degree=3, dxfattribs={'layer': 'BricsCAD B-spline', 'color': 2})
doc.saveas(DIR / 'tangents-estimated.dxf')

И удивительно, что оценки не верны, сплайн BricsCAD имеет касательные углы 101.0035408517495 и -101.0035408517495 градусов.

splines do not match again

И действительно раздражает то, что если я использую углы BricsCAD в качестве входных данных, сплайны все равно не совпадают, поэтому я предположил, что оценка тангенциальной величины отличается от сценарий 2.

4. Проверка теории

Следующие значения вычисляются из файла DXF, сохраненного BricsCAD, и SPLINE «Метод» переключен с «точек подгонки» на «контрольные вершины». По этим данным я вычислил касательные углы, а также величины, tangent vector = 2nd control vertex - 1st control vertex

required_angle = 101.0035408517495  # angle of tangent vector in degrees
required_magnitude = m1 * 1.3097943444804256  # magnitude of tangent vector
start_tangent = Vector.from_deg_angle(required_angle, required_magnitude)
end_tangent = Vector.from_deg_angle(-required_angle, required_magnitude)
s = global_bspline_interpolation(points, degree=3, tangents=(start_tangent, end_tangent))
msp.add_spline(dxfattribs={'color': 4, 'layer': 'Global Interpolation'}).apply_construction_tool(s)
msp.add_spline(points, degree=3, dxfattribs={'layer': 'BricsCAD B-spline', 'color': 2})
doc.saveas(DIR / 'theory-check.dxf')

Теперь шлицы снова совпадают:

now the splines match again

  1. Если касательные заданы (сохранены в DXF), величина входных касательных для функции интерполяции равна «общей длине хорды».
  2. Без заданных касательных величина отличается, в этом примере: m1*1.3097943444804256, но это не постоянный коэффициент.

Большой вопрос: Как оценить начальную и конечную касательные по направлению и величине, как в AutoCAD или BricsCAD для сплайнов, определяемых только подходят точки?

Заранее спасибо,

Манфред

1 Ответ

0 голосов
/ 02 сентября 2020

Объект SPLINE может иметь необязательный групповые коды 12,22,32 для начальной касательной x, y, z и 13,23,33 для конечной касательной x, y, z. Я проверил исходный код проекта netDxf, и из этого следует, что если для определения сплайна используются только точки подгонки, то необходимо указать начальное и конечное значения касательной .

Из AutoCAD Ссылка 2012 DXF для объекта SPLINE:

12 Начальная касательная - может быть опущено (в WCS) DXF: значение X; APP: 3D-точка

22, 32 DXF: значения Y и Z начальной касательной - могут быть опущены (в WCS)

13 Конечная касательная - могут быть опущены (в WCS) DXF: X стоимость; ПРИЛОЖЕНИЕ: 3D-точка

23, 33 DXF: значения Y и Z конечной касательной - могут быть опущены (в WCS)

Вчера мы вместе с моим коллегой создали несколько файлов DXF. Autocad 2020, включая шлицы по точкам посадки. После экспорта в DXF шлицы определялись контрольными точками и узлами. Так что я предполагаю, что очки подгонки - это что-то устаревшее или предназначенное только для пользовательского интерфейса.

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