4

试图让那个中心区域充满,不知道我做错了什么。

在此处输入图像描述

Imports System.Drawing.Drawing2D

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        Dim gp As GraphicsPath = CreatePath(New Rectangle(New Point(200, 200), New Size(250, 100)))
        e.Graphics.FillPath(New SolidBrush(Color.LightBlue), gp)
        e.Graphics.DrawPath(New Pen(Color.Black), gp)

    End Sub

    Private Function CreatePath(ByVal area As Rectangle) As GraphicsPath

        Dim gp As New GraphicsPath()
        Dim rect As Rectangle = New Rectangle(area.Location, New Size(area.Width, area.Height \ 3))
        gp.AddEllipse(rect)

        Dim hadj As Integer = area.Height \ 4
        gp.AddLine(New Point(area.X, area.Y + area.Height - hadj), New Point(area.X, area.Y + (rect.Height \ 3) + 8))

        Dim gh As Integer = area.Width \ 4
        Dim pts(4) As PointF
        pts(0) = New PointF(area.X, area.Y + area.Height - hadj)
        pts(1) = New Point(area.X + gh, area.Y + area.Height - (hadj \ 2))
        pts(2) = New Point(area.X + gh * 2, area.Y + area.Height - (hadj \ 3))
        pts(3) = New Point(area.X + gh * 3, area.Y + area.Height - (hadj \ 2))
        pts(4) = New Point(area.X + area.Width, area.Y + area.Height - hadj)
        gp.AddCurve(pts)

        gp.AddLine(New PointF(area.X + area.Width, area.Y + (rect.Height \ 3) + 9), New PointF(area.X + area.Width, area.Y + area.Height - hadj))
        Return gp
    End Function
End Class
4

2 回答 2

4

试试下面的。默认情况下,GraphicsPath 使用交替填充模式,交替添加/减去填充。缠绕填充模式使用方向从填充中添加(顺时针)或减去(逆时针)。

Private Function CreatePath(ByVal area As Rectangle) As GraphicsPath
    '* Set fill mode to winding (see FillMode Help)
    Dim gp As New GraphicsPath(FillMode.Winding)

    Dim rect As Rectangle = New Rectangle(area.Location, New Size(area.Width, area.Height \ 3))
    gp.AddEllipse(rect)

    '* Reorder points so that path goes clockwise (see FillMode.Winding Help)

    Dim hadj As Integer = area.Height \ 4
    'Left side bottom -> top
    'gp.AddLine(New Point(area.X, area.Y + area.Height - hadj), New Point(area.X, area.Y + (rect.Height \ 3) + 8))

    '* Right side top -> bottom (clockwise)
    '* NOTE: Top Y value was a bit too high, adjusted by -3.  Adjust calculation or maybe use floating point math and used rounding, ceil, or floor
    gp.AddLine(New PointF(area.X + area.Width, area.Y + (rect.Height \ 3) + 9 - 3), New PointF(area.X + area.Width, area.Y + area.Height - hadj))

    Dim gh As Integer = area.Width \ 4
    Dim pts(4) As PointF
    'pts(0) = New PointF(area.X, area.Y + area.Height - hadj)
    'pts(1) = New Point(area.X + gh, area.Y + area.Height - (hadj \ 2))
    'pts(2) = New Point(area.X + gh * 2, area.Y + area.Height - (hadj \ 3))
    'pts(3) = New Point(area.X + gh * 3, area.Y + area.Height - (hadj \ 2))
    'pts(4) = New Point(area.X + area.Width, area.Y + area.Height - hadj)
    '* Reordered points (clockwise)
    pts(0) = New Point(area.X + area.Width, area.Y + area.Height - hadj)
    pts(1) = New Point(area.X + gh * 3, area.Y + area.Height - (hadj \ 2))
    pts(2) = New Point(area.X + gh * 2, area.Y + area.Height - (hadj \ 3))
    pts(3) = New Point(area.X + gh, area.Y + area.Height - (hadj \ 2))
    pts(4) = New PointF(area.X, area.Y + area.Height - hadj)
    gp.AddCurve(pts)

    'Right side top -> bottom
    'gp.AddLine(New PointF(area.X + area.Width, area.Y + (rect.Height \ 3) + 9), New PointF(area.X + area.Width, area.Y + area.Height - hadj))

    '* Left side bottom -> top (clockwise)
    '* NOTE: Top Y value was a bit too high, adjusted by -2.  Adjust calculation or maybe use floating point math and used rounding, ceil, or floor
    gp.AddLine(New Point(area.X, area.Y + area.Height - hadj), New Point(area.X, area.Y + (rect.Height \ 3) + 8 - 2))

    Return gp
End Function
于 2019-02-12T18:14:11.270 回答
2

另一种方法,只是为了显示对象的Reset()方法GraphicsPath
由于圆柱体可以看作是两个椭圆和一个矩形的组合(透视创建了 3D 对象的错觉),因此这里首先填充这些形状,然后独立绘制外部部分(形状边框)。

如果需要,这最终将允许为图形使用不同的画笔。

结果样本:

图形路径圆柱体


Private upperRect As Rectangle = New Rectangle(New Point(10, 10), New Size(180, 80))
Private lowerRect As Rectangle = New Rectangle(New Point(10, 100), New Size(180, 80))

Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

    Dim middleRect As Rectangle = CylinderMiddleRect(upperRect, lowerRect)

    Using gp As New GraphicsPath(FillMode.Winding)
        gp.AddEllipse(upperRect)
        gp.AddRectangle(middleRect)
        gp.AddEllipse(lowerRect)
        e.Graphics.FillPath(Brushes.LightBlue, gp)
        gp.Reset()

        gp.AddArc(lowerRect, 0, 180)
        gp.AddEllipse(upperRect)
        gp.AddLine(New Point(middleRect.X, middleRect.Y), New Point(upperRect.X, middleRect.Bottom))
        gp.CloseFigure()
        gp.AddLine(New Point(middleRect.Right, middleRect.Y), New Point(middleRect.Right, middleRect.Bottom))
        gp.CloseFigure()
        e.Graphics.DrawPath(Pens.Black, gp)
    End Using
End Sub

Private Function CylinderMiddleRect(upperRect As Rectangle, lowerRect As Rectangle) As Rectangle
    Dim distance = (lowerRect.Y + (lowerRect.Height \ 2)) - (upperRect.Y + (upperRect.Height \ 2))

    Return New Rectangle(New Point(upperRect.X, upperRect.Y + (upperRect.Height \ 2)),
                         New Size(upperRect.Width, distance))
End Function
于 2019-02-12T19:22:52.313 回答