简体   繁体   English

vb.NET - 如何在不包含贝塞尔曲线句柄位置的情况下获取 GraphicsPath 的边界

[英]vb.NET - How to Get boundary of GraphicsPath without including Bezier handle locations

I'm trying to do a boundary around a GraphicsPath for easy group sizing.我正在尝试围绕 GraphicsPath 设置边界以便于调整组大小。 This works fine but when I convert one of the points to a bezier it includes the location of the Bezier handles within the boundary making the selection rectangle much larger than it is supposed to be.这很好用,但是当我将其中一个点转换为贝塞尔曲线时,它包括边界内贝塞尔曲线图柄的位置,从而使选择矩形比预期的大得多。

Here is how it looks when the path is first created, by default the points are lines only without beziers.这是第一次创建路径时的样子,默认情况下,点只是没有贝塞尔曲线的线。 Selection rectangle works as expected.选择矩形按预期工作。

lines not beziers are right线条不是贝塞尔曲线是正确的

When I double click on a point it automatically converts the points to a bezier (or if bezier, toggles back to Line) and then the selection rectangle reflects the handle points as well in the path.当我双击一个点时,它会自动将点转换为贝塞尔曲线(或者如果是贝塞尔曲线,则切换回直线),然后选择矩形也会在路径中反映手柄点。

when using beziers path is bigger当使用 beziers 路径更大时

As you can see, it should stop the rectangle just under the curve made by the bezier but it also seems to expand to the handles.如您所见,它应该在贝塞尔曲线下方的矩形停止,但它似乎也扩展到手柄。

Here is the code for doing the rectangle perimeter.这是做矩形周边的代码。


Public Overrides Sub DrawSelectionRectangle(ByVal g As Graphics) SelectionRectangle = New RectangleF(0, 0, 0, 0)公共重写 Sub DrawSelectionRectangle(ByVal g As Graphics) SelectionRectangle = New RectangleF(0, 0, 0, 0)

Dim GP As GraphicsPath = _lastGp 'DAVE将 GP 调暗为 GraphicsPath = _lastGp 'DAVE

If GP IsNot Nothing Then If _lastGp.PointCount > 1 Then Try Dim BH As New Single: Dim TH As New Single: Dim LW As New Single: Dim RW As New Single If GP IsNot Nothing Then If _lastGp.PointCount > 1 Then Try Dim BH As New Single: Dim TH As New Single: Dim LW As New Single: Dim RW 作为新单曲

  TH = GP.PathPoints(0).Y
  LW = GP.PathPoints(0).X

  For i = 0 To GP.PathPoints.Length - 1
   With GP.PathPoints(i)
    If .Y < TH Then TH = .Y
    If .X < LW Then LW = .X
    If .Y > BH Then BH = .Y
    If .X > RW Then RW = .X
   End With

  Next i

  'DAVE - This code won't work as it doesn't factor in for space made by the actual bezier curves, GP path must be followed. BUT! this is a tidier solution.
  'SelectionRectangle = New RectangleF(0, 0, 0, 0)
  'If _pointArray IsNot Nothing Then
  ' If _pointArray.Count > 1 Then
  '  Try
  '   Dim BH As New Single : Dim TH As New Single : Dim LW As New Single : Dim RW As New Single

  '   LW = _pointArray(0).P.X
  '   TH = _pointArray(0).P.Y

  '   For i = 0 To _pointArray.Count - 1
  '    With _pointArray(i).P
  '     If .Y < TH Then TH = .Y
  '     If .X < LW Then LW = .X
  '     If .Y > BH Then BH = .Y
  '     If .X > RW Then RW = .X
  '    End With

  '   Next i
  '=================================

  SelectionRectangle = New RectangleF(New PointF(LW, TH), New SizeF(RW - LW, BH - TH))

  Dim r As RectangleF = DrawRectangle.GetNormalizedRectangle(SelectionRectangle)
  Dim gpen As Pen = New Pen(Color.Gray, MyBase.StrokeWidth)
  gpen.DashStyle = DashStyle.Dash
  g.DrawRectangle(gpen, r.X, r.Y, r.Width, r.Height)

  gpen.Dispose()
 Catch ex As Exception
  ErrH.Log("DrawSelectionRectangle", "Draw", ex.ToString(), ErrH._LogPriority.Info)
 End Try

End If

End If万一

End Sub结束子


Any help on a simple solution would be much appreciated.对简单解决方案的任何帮助将不胜感激。 :) :)

I have tried using the actual point array as a reference but this does not factor in for the curves thrown by the Bezier.我试过使用实际的点数组作为参考,但这并没有考虑到贝塞尔曲线抛出的曲线。 See example if the above commented code is run.如果运行上述注释代码,请参见示例。

trying to follow path array instead of graphics path试图遵循路径数组而不是图形路径

WOW...哇...

That took a while but I found the answer!这花了一段时间,但我找到了答案!

Literally 1 line!字面意思是1行!

GP.Flatten GP.扁平化

The fixed line固定线路

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM