You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用渐变填充椭圆扇形区域并实现旋转圆锥视觉效果?

解决WinForms环形区域填充问题及实现渐变圆锥效果

问题说明

此前用DirectX实现过旋转圆锥视觉效果,现在尝试用C# WinForms绘制环形区域,但遇到以下问题:

  • 即使将thickness设为50及以上,环形区域仍无法正常填充
  • 希望在thickness≤20或innerR变化时,也能稳定填充弧形区域
  • 最终目标:实现任意参数下的弧形区域填充,并用渐变填充椭圆扇形模拟圆锥效果

原代码问题分析

原代码的GraphicsPath构造逻辑有误:当arcLength=360时,两段整圆弧形的路径未通过线段连接,导致FillPath无法识别中间的填充范围;当arcLength非360时,路径闭合方向也存在问题,引发填充失效。

修正后的环形填充代码

调整路径构造逻辑,通过线段连接外弧与内弧的对应端点,形成可填充的闭合环形区域:

public partial class Form1 : Form
{
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        var g = e.Graphics;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        var center = new Point(pictureBox1.Width / 2, pictureBox1.Height / 2);
        int innerR = 30;
        int thickness = 20;
        float startAngle = 0;
        float arcLength = 360; // 可改为任意角度,如180、90
        int outerR = innerR + thickness;

        var outerRect = new Rectangle(center.X - outerR, center.Y - outerR, 2 * outerR, 2 * outerR);
        var innerRect = new Rectangle(center.X - innerR, center.Y - innerR, 2 * innerR, 2 * innerR);

        using (var path = new System.Drawing.Drawing2D.GraphicsPath())
        {
            // 添加外圆弧
            path.AddArc(outerRect, startAngle, arcLength);
            // 连接外弧终点到内弧终点
            float endAngle = startAngle + arcLength;
            PointF outerEnd = GetArcEndPoint(center, outerR, endAngle);
            PointF innerEnd = GetArcEndPoint(center, innerR, endAngle);
            path.AddLine(outerEnd, innerEnd);
            // 添加反向内圆弧
            path.AddArc(innerRect, endAngle, -arcLength);
            // 连接内弧起点到外弧起点,闭合路径
            PointF innerStart = GetArcEndPoint(center, innerR, startAngle);
            path.AddLine(innerStart, new Point(center.X + outerR, center.Y + outerR));
            path.CloseFigure();

            g.FillPath(Brushes.Green, path);
            g.DrawPath(Pens.DarkGreen, path);
        }
    }

    // 辅助方法:计算圆弧端点坐标
    private PointF GetArcEndPoint(Point center, int radius, float angle)
    {
        float radian = angle * (float)Math.PI / 180;
        float x = center.X + radius * (float)Math.Cos(radian);
        float y = center.Y + radius * (float)Math.Sin(radian);
        return new PointF(x, y);
    }
}

渐变圆锥效果实现

通过PathGradientBrush实现中心到边缘的光影渐变,模拟圆锥视觉效果:

public partial class Form1 : Form
{
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        var g = e.Graphics;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        var center = new Point(pictureBox1.Width / 2, pictureBox1.Height / 2);
        int innerR = 0; // 圆锥顶点在中心,设为0
        int thickness = 150; // 圆锥底面半径
        float startAngle = 30; // 圆锥起始角度
        float arcLength = 120; // 圆锥扇形角度
        int outerR = innerR + thickness;

        var outerRect = new Rectangle(center.X - outerR, center.Y - outerR, 2 * outerR, 2 * outerR);

        using (var path = new System.Drawing.Drawing2D.GraphicsPath())
        {
            // 构建圆锥扇形路径:中心→外弧起点→外弧→中心
            PointF outerStart = GetArcEndPoint(center, outerR, startAngle);
            path.AddLine(center, outerStart);
            path.AddArc(outerRect, startAngle, arcLength);
            PointF outerEnd = GetArcEndPoint(center, outerR, startAngle + arcLength);
            path.AddLine(outerEnd, center);
            path.CloseFigure();

            // 创建渐变画刷:中心亮白,边缘暗橙
            using (var brush = new System.Drawing.Drawing2D.PathGradientBrush(path))
            {
                brush.CenterColor = Color.White;
                brush.SurroundColors = new[] { Color.DarkOrange };
                brush.CenterPoint = center;
                g.FillPath(brush, path);
                g.DrawPath(Pens.Brown, path);
            }
        }
    }

    private PointF GetArcEndPoint(Point center, int radius, float angle)
    {
        float radian = angle * (float)Math.PI / 180;
        float x = center.X + radius * (float)Math.Cos(radian);
        float y = center.Y + radius * (float)Math.Sin(radian);
        return new PointF(x, y);
    }
}

关键说明

  • GetArcEndPoint方法精确计算圆弧端点,确保路径连接无偏差
  • 环形填充通过线段连接内外弧端点,形成闭合的可填充区域
  • 圆锥效果通过将innerR设为0,配合路径渐变画刷实现自然光影过渡

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:20:47