autocad - AutoCAD 如何计算仅由拟合点定义的样条曲线的端切线?

标签 autocad spline dxf

AutoCAD 允许将 SPLINE 实体存储在仅由
拟合点,问题是,这样的样条定义有无限
数值正确的解决方案,Autodesk 不提供必要的
从给定的拟合点计算所需参数的信息。

tl;dr - 缺失的信息是估计的起点和终点切线
全局 B 样条输入切线的方向和幅度
用末端导数插值,有人可以帮助计算这个值吗?

Complete source code on 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:“The NURBS Book” - 第 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 样条,但是开始和
端切线不像场景 1 那样存储在 DXF 文件中。
需要估计起点和终点切线,最佳结果为:
来自“The NURBS Book”的“5 Point Interpolation”,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. 理论检查

以下值是根据 BricsCAD 保存的 DXF 文件计算得出的
和 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
  • 如果给定切线(存储在 DXF 中),则输入切线的幅度
    插值函数是“总弦长”。
  • 没有给定的切线,大小是不同的,在这个例子中:m1*1.3097943444804256 ,
    但它不是一个恒定的因素。

  • 最大的问题是:如何估计方向和大小的起点和终点切线
    像 AutoCAD 或 BricsCAD 用于仅由拟合点定义的样条曲线?


    提前致谢,

    曼弗雷德

    最佳答案

    SPLINE 实体可以有 可选 起始切线 x,y,z 的组代码为 12,22,32,结束切线 x,y,z 的组代码为 13,23,33。我检查了 netDxf 项目的源代码,如果仅使用拟合点来定义样条,则开始和结束切线值 将被指定 .
    从 AutoCAD 2012 DXF Reference for SPLINE 实体:

    12 Start tangent—may be omitted (in WCS) DXF: X value; APP: 3D point

    22, 32 DXF: Y and Z values of start tangent—may be omitted (in WCS)

    13 End tangent—may be omitted (in WCS) DXF: X value; APP: 3D point

    23, 33 DXF: Y and Z values of end tangent—may be omitted (in WCS)


    昨天我们和我的同事在 Autocad 2020 中创建了一些 DXF 文件,包括拟合点样条。导出到 DXF 后,样条由控制点和节点定义。所以我猜测拟合点已经过时或仅用于 UI。

    关于autocad - AutoCAD 如何计算仅由拟合点定义的样条曲线的端切线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62472305/

    相关文章:

    python - 图像变形场的 B 样条插值

    geometry - 弧变换起点终点到起点角度终点角度

    lisp - 在 autocad 的连接点上打破多段线 - 任何 lisp 函数?

    autocad - DXF 文件 - 无法在 Autodesk Viewer 中打开

    使用 mgcv gam 运行随机误差模型需要太多内存

    c++ - 对 3D 空间中的样条插值感到困惑

    java - DXF 文件插入实体

    AutoCAD - 在子文件夹中另存为 DXF

    .net - 加载AutoCAD插件的顺序是什么?

    lisp - 如何在 AutoLisp 中访问带引号的变量数据?