使用 PathGeometry.Widen() 时带有 StrokeStyle 的不需要的端盖

Undesired End-Caps with StrokeStyle when using PathGeometry.Widen()

我正在使用 SharpDX 在 .NET WinForms 上绘制折线。 这些折线表示钣金件的轮廓。

组成一个 PathGeometry 对象,定义多段线:

'reset m_pathGeometry (the core geometry of this sheetmetal profile)
m_pathGeometry = New PathGeometry(D2DCanvas.canvas_factory2D)

' pointsRef = collection of points showing the segments & bends in this sheetmetal profile
Dim pointsRef As List(Of Vector2) = calculateSegmentsPoints()

' Add lines to m_pathGeometry using our points collection
Using sink As SimplifiedGeometrySink = m_pathGeometry.Open()
    sink.BeginFigure(pointsRef.First(), FigureBegin.Filled)
    sink.AddLines(pointsRef.ToArray)
    sink.EndFigure(FigureEnd.Open)
    sink.Close()
End Using

在被绘制到屏幕之前,我应用了一个变换(考虑到变换和缩放):

' update m_fillTransformedGeometry based on m_pathGeometry & the current transform matrix3x2,
m_fillTransformedGeometry = New TransformedGeometry(D2DCanvas.canvas_factory2D, m_pathGeometry, Matrix3x2.Rotation(m_rotation, InsertPoint) * _transformMatrix)

' to draw the polyline
D2DCanvas.canvas_renderTarget2D.DrawGeometry(m_fillTransformedGeometry, m_fillBrush, plaatdikte * _transformMatrix.ScaleVector(1), m_strokeStyle)

使用笔触样式、圆角线连接和平端帽绘制多段线

With m_strokeStyleProps
   .LineJoin = LineJoin.Round
   .EndCap = CapStyle.Flat
   .StartCap = CapStyle.Flat
End With

结果有点苍白,可以用一笔:

第一个想法 是用较深的颜色绘制相同的多段线,并使用稍宽的 StrokeWidth:

' First draw a wider stroke
D2DCanvas.canvas_renderTarget2D.DrawGeometry(m_fillTransformedGeometry, m_strokeBrush, (plaatdikte + 0.2) * _transformMatrix.ScaleVector(1), m_strokeStyle)

' Then draw the fill
D2DCanvas.canvas_renderTarget2D.DrawGeometry(m_fillTransformedGeometry, m_fillBrush, plaatdikte * _transformMatrix.ScaleVector(1), m_strokeStyle)

结果不错,但端盖没有这样描边:

第二个想法 是通过调用 Widen() 方法为笔划本身创建一个(稍微加宽的)PathGeometry折线-PathGeometry.

'define m_widenedPathGeometry (makes op the outline/stroke of this sheetmetal profile)
m_widenedPathGeometry = New PathGeometry(D2DCanvas.canvas_factory2D)
Using sink As SimplifiedGeometrySink = m_widenedPathGeometry.Open()
    m_pathGeometry.Widen(0.2, sink)
    sink.Close()
End Using

在绘制 'fill'(均使用相同的 StrokeStyle!)之前,将此加宽的几何图形绘制(考虑到变换)为 'stroke':

' update m_transGeom based on m_widenedPathGeometry & the current transform matrix3x2,
m_transGeom = New TransformedGeometry(D2DCanvas.canvas_factory2D, m_widenedPathGeometry, Matrix3x2.Rotation(m_rotation, InsertPoint) * _transformMatrix)
'   to draw the stroke of the Polyline
D2DCanvas.canvas_renderTarget2D.DrawGeometry(m_transGeom, m_strokeBrush, plaatdikte * _transformMatrix.ScaleVector(1), m_strokeStyle)

' update m_fillTransformedGeometry based on m_pathGeometry & the current transform matrix3x2,
m_fillTransformedGeometry = New TransformedGeometry(D2DCanvas.canvas_factory2D, m_pathGeometry, Matrix3x2.Rotation(m_rotation, InsertPoint) * _transformMatrix)
' to draw the fill of the PolyLine
D2DCanvas.canvas_renderTarget2D.DrawGeometry(m_fillTransformedGeometry, m_fillBrush, plaatdikte * _transformMatrix.ScaleVector(1), m_strokeStyle)

这会对 End-Caps 产生不良影响: (要么是圆形,要么是 StrokeStyle 中没有定义的,要么是介于两者之间的东西)

这个 Stroke/Fill - 当我重新定义使用的 StrokeStyle 以具有 'rounded' 端盖时,方法 kindof 工作正常:

但 'flat' 结尾才是我真正想要的。

知道为什么会发生这种情况,或者我可以如何以不同的方式解决这个问题?

干杯!

发现这里出了什么问题!

为可能遇到类似情况的其他人写下此内容。

在创建加宽的几何体时,我添加了 'FigureEnd' 属性 设置为 'Open',这防止了在其自身上创建 'closed loop' 的几何体,导致这些工件。

m_widenedPathGeometry = New PathGeometry(D2DCanvas.canvas_factory2D)
Using sink As SimplifiedGeometrySink = m_widenedPathGeometry.Open()
    m_pathGeometry.Widen(0.2, sink)
    **sink.EndFigure(FigureEnd.Open)**   <- adding this line leaves the stroke open!
    sink.Close()
End Using