圆弧图形质量(Arc graphic quality)

2019-09-28 16:45发布

回到这里。 有没有什么办法来提高电弧的质量?
我使用e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

这是一段代码,创建弧:

using (GraphicsPath gp = new GraphicsPath())
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    gp.Reset();
    gp.AddPie(_OuterRectangle, (float)_Properties.Origin, (float)_Properties.GaugeType);
    gp.Reverse();

    gp.AddPie(_InnerRectangle, (float)_Properties.Origin, (float)_Properties.GaugeType);
    gp.Reverse();
    pArea.SetClip(gp);

    using (Pen oPen = new Pen(this.ForeColor, 2f))
    {
       e.Graphics.DrawPath(oPen, gp);
    }
    e.Graphics.SetClip(ClientRectangle);
}

提前致谢。

编辑:
我做了什么LarsTech提出,现在的质量是完美的,但我并没有这个数字,我需要:

  • OuterRectangle:是ClientRectangle面积,说我操纵它,使宽度和高度相同lenght;
  • InnerRectangle:是ClientRectangle区域,因此,这个OuterRectangle的2 / 3ths;
  • Properties.Origin:是在起弧的角度。 我有它在枚举作为基点,其中北美为270,东为0,
    所以。 在该图的情况下,是西南,135度;

  • Properties.GaugeType:是另一个枚举说,如果是完整= 360,半= 180,四分之一= 90,所以与我可以确定后掠角。 在该图的情况下是ThreeQuarter,270度。

Answer 1:

问题
当截割当前图形(的区域Graphics.SetClip方法),所得到的拉丝失去的质量,因为所产生的效果抗锯齿Graphics.SmoothingMode = SmoothingMode.AntiAlias丢失。

一种可能的解决方案是,以避免削波由限定的区域GraphicsPath用于设计弧( GraphicsPath.AddPie方法); 这一点,但是,叶派可见的线,影响的形状。

另一种解决方案是在使用Canvas的背景颜色的圆弧的中心绘制省略号。 由于电弧使用两个矩形绘制,我们可以使用内rectagle,它充气( Rectangle.Inflate根据需要法)(级分- Pen.Width / 2 -用于ouline笔的尺寸,通常情况下)。

这允许删除由所产生的工件GraphicsPath形状和画在形状的中心一些其他图形内容。

例如,使用不同的刷子:

  LinearGradientBrush           HatchBrush               TextureBrush

当然也有其他的方法来达到同样的效果。 我们可以借鉴使用弧线GraphicsPath.AddArc方法,提取或计算弧的第一个和最后一个点,并用它们来画两条线( GraphicsPath.AddLine ),将关闭数字。

但是,因为我们想在圆弧的中心绘制不同的图形对象,这些对象将覆盖反正中心区域。

如何使用此代码

  • 在窗体中添加一个跟踪条 (被称为tbarSpeed ,这里)
  • 添加一个面板 (称为Canvas ),大小为(200, 200) 使用这里提供的自定义面板控制,它增加了一些ControlStyles在其costructor。 这将避免闪烁和文物
  • 线了跟踪条tbarSpeed_Scroll事件和面板Canvas_Paint事件。

using System.Drawing;
using System.Drawing.Drawing2D;


float GaugeValue = 88.0f;
float GaugeSweepAngle = 270.0f;
float GaugeStartAngle = 135.0F;

private void Canvas_Paint(object sender, PaintEventArgs e)
{
    Control canvas = sender as Control;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    Rectangle outerRectangle = new Rectangle(10, 10, 180, 180);
    Rectangle innerRectangle = new Rectangle(30, 30, 140, 140);
    Rectangle blendRectangle = new Rectangle(10, 10, 180, 160);
    PointF innerCenter = new PointF(outerRectangle.Left + (outerRectangle.Width / 2),
                                    outerRectangle.Top + (outerRectangle.Height / 2));
    float gaugeLength = (outerRectangle.Width / 2) - 2;

    using (GraphicsPath path = new GraphicsPath())
    {
        path.AddPie(outerRectangle, GaugeStartAngle, GaugeSweepAngle);
        path.AddPie(innerRectangle, GaugeStartAngle, GaugeSweepAngle);
        innerRectangle.Inflate(-1, -1);

        using (Pen pen = new Pen(Color.White, 3f))
        using (SolidBrush backgroundbrush = new SolidBrush(canvas.BackColor))
        using (LinearGradientBrush gradientBrush = new LinearGradientBrush(blendRectangle,
               Color.Green, Color.Red, LinearGradientMode.ForwardDiagonal))
        {
            Blend blend = new Blend()
            {
                Factors = new[] { 0.0f, 0.0f, 0.1f, 0.3f, 0.7f, 1.0f },
                Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }
            };

            gradientBrush.Blend = blend;
            e.Graphics.FillPath(gradientBrush, path);
            e.Graphics.DrawPath(pen, path);

            e.Graphics.FillEllipse(backgroundbrush, innerRectangle);

            using (StringFormat format = new StringFormat())
            {
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                innerRectangle.Location = new Point(innerRectangle.X, innerRectangle.Y + canvas.Font.Height);
                e.Graphics.DrawString(GaugeValue.ToString() + "%", canvas.Font, Brushes.White, innerRectangle, format);
            }

            using (Matrix matrix = new Matrix())
            {
                matrix.RotateAt(GaugeStartAngle + 90 + (GaugeValue * (GaugeSweepAngle / 100)), innerCenter);
                e.Graphics.Transform = matrix;
                e.Graphics.DrawLine(pen, innerCenter, new PointF(innerCenter.X, innerCenter.Y - gaugeLength));
                e.Graphics.ResetTransform();
            }
        }
    }
}

private void tbarSpeed_Scroll(object sender, EventArgs e)
{
    GaugeValue = tbarSpeed.Value;
    Canvas.Invalidate();
}

自定义面板控制

using System.ComponentModel;
using System.Windows.Forms;

[DesignerCategory("code")]
public class DrawingPanel : Panel
{
    public DrawingPanel()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.UserPaint |
                      ControlStyles.OptimizedDoubleBuffer, true);
        this.UpdateStyles();
    }
}

在引擎收录示例代码



文章来源: Arc graphic quality