C#管道控件,中间管道填充渐变色与预想的不符?

发布于 2022-09-13 00:35:51 字数 3639 浏览 33 评论 0

画一个如下图的管道控件,要求在设计器里可以拉伸改变管道的倾斜度,但是目前中间的管道渐变颜色一直控制不好,下面跟管弯对不上,求大佬助我!

我自己研究了下,稍微有点思路:

我画了个三角形找到管道直管段的垂线黄色线段(事后证明不是垂线=。=),拉伸的时候渐变位置变化了。

现在的问题是如何能找到上图两条平行线的垂线?然后算出垂线跟平行线的焦点坐标,以这2个坐标填充渐变应该可以保证拉伸的情况下保持渐变不变形。

附上控件代码,求大佬帮我改下代码,感激不尽!!!

public partial class PipeLine : UserControl
{
    public PipeLine()
    {
        InitializeComponent();
        SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
        base.OnPaint(e);
        Graphics graphics = e.Graphics;
 
        int pipeLineWidth = 50;//管道宽度
        ColorBlend colorBlend = new ColorBlend();
        colorBlend.Positions = new float[3] { 0f, 0.5f, 1f };
        colorBlend.Colors = new Color[3] { Color.DimGray, Color.LightGray, Color.DimGray };
        GraphicsPath path = new GraphicsPath();
 
        double angleUp = Math.Atan((ClientRectangle.Height - pipeLineWidth) / (double)ClientRectangle.Width);
        angleUp = angleUp / Math.PI * 180f;
 
        path.AddLine(new Point(ClientRectangle.Right, ClientRectangle.Top + pipeLineWidth), new Point((int)(ClientRectangle.Right + 1 - Math.Sin(Math.PI * (angleUp / 180.00F)) * pipeLineWidth), (int)(ClientRectangle.Top + pipeLineWidth - Math.Cos(Math.PI * (angleUp / 180.00F)) * pipeLineWidth)));
        path.AddLine(new Point(ClientRectangle.Left, ClientRectangle.Bottom - pipeLineWidth), new Point((int)(ClientRectangle.Left + 1 + Math.Sin(Math.PI * (angleUp / 180.00F)) * pipeLineWidth), (int)(ClientRectangle.Bottom - pipeLineWidth + Math.Cos(Math.PI * (angleUp / 180.00F)) * pipeLineWidth + 2)));
        path.CloseAllFigures();
 
        LinearGradientBrush line_Brush = new LinearGradientBrush(new Point((int)(ClientRectangle.Right + 1 - Math.Sin(Math.PI * (angleUp / 180.00F)) * pipeLineWidth), (int)(ClientRectangle.Top + pipeLineWidth - Math.Cos(Math.PI * (angleUp / 180.00F)) * pipeLineWidth)), new Point(ClientRectangle.Right, ClientRectangle.Top + pipeLineWidth), Color.DimGray, Color.LightGray);
 
        line_Brush.InterpolationColors = colorBlend;
        graphics.FillPath(line_Brush, path);
 
        //上圆弧
        PaintEllipse(graphics, colorBlend, new Rectangle(ClientRectangle.Right - pipeLineWidth, ClientRectangle.Top, pipeLineWidth * 2, pipeLineWidth * 2), 270, -1 * (float)angleUp);
        //下圆弧
        PaintEllipse(graphics, colorBlend, new Rectangle(ClientRectangle.Left - pipeLineWidth, ClientRectangle.Bottom - pipeLineWidth * 2, pipeLineWidth * 2, pipeLineWidth * 2), 90, -1 * (float)angleUp);
    }
    void PaintEllipse(Graphics g, ColorBlend colorBlend, Rectangle rect, float startAngle, float sweepAngle)
    {
        GraphicsPath graphicsPath = new GraphicsPath();
        graphicsPath.AddEllipse(rect);
        PathGradientBrush pathGradientBrush = new PathGradientBrush(graphicsPath);
        pathGradientBrush.CenterPoint = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
        pathGradientBrush.InterpolationColors = colorBlend;
        g.FillPie(pathGradientBrush, rect, startAngle, sweepAngle);
        g.DrawArc(new Pen(Color.DimGray, 1f), rect, startAngle, sweepAngle);
        pathGradientBrush.Dispose();
        graphicsPath.Dispose();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅听莫相离 2022-09-20 00:35:51


搞定了,上图橘黄色是LinearGradientBrush的渐变方向。
利用直线斜率找出一条斜边的垂线,然后找到垂线跟两条平行斜边的交点得出渐变坐标点。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文