2011-02-15 17 views
0

나는 그래픽 경로에 "도넛"이 있습니다.GDIPlus 원형 GraphicsPath 따라 그라데이션

나는 그 경로를 따라 그라디언트를 그려서 원색의 시작 및 끝 각도로 색상이 시작되고 끝날 때 제어하려고합니다. 이 같은

,

http://www.andresilvadesign.com/wp-content/uploads/2011/01/Gauge-icon-design.jpg

linearGradint은 하나의 각도를 갈 수 있고, 적절하게 경로를 따라하지 않습니다.

PathGradientBrush가 순환 그라디언트처럼 보입니까? C에서이 작업을 올바르게 수행하는 방법을 찾지 못하는 것 같습니다 #

어떤 도움을 많이 주시면 감사하겠습니다!

답변

0

PathGradientBrush를 사용하여 완전한 원을 그린 다음 마스크하거나, 이미지와 같은 게이지면으로 말하거나, 배경색으로 원 (및/또는 원형 웨지)으로 표시 할 수 있습니까?

+0

내가 어떻게 될까요? 그라디언트를 안쪽에서 바깥쪽으로 이동시키려는 메신저? – Aviel

+0

그라디언트에 원호를 따르는 방법이 있습니다. 이 사이트를 방문하십시오 : http://www.bobpowell.net/pgb.htm – KeithS

+0

경로/호를 따라 그라디언트를 얻는 방법을 설명하는 웹 사이트에서는 아무것도 찾을 수 없습니다. KeithS – Aviel

0

나는 이것이 꽤 오래되었다는 것을 알고 있으며 저자는 더 이상 신경 쓰지 않을 것이라고 생각하지만이 웹 사이트에서이 질문에 대한 답변을 검색했으며 아무 것도 찾을 수 없었다.

bobpowell.net/pgb.htm은 커브를 그리는 데 사용 된 실제 숫자를 얻을 수있는 방법을 찾지 못해서 저에게 맞지 않았습니다. ("둘러싸인 단락"참조)

(나는 코드를 향상시키기위한 제안이 매우 환영합니다. 특히 내 가장자리는 다음과 같습니다. 약간의 퍼지)

아이디어는 도넛처럼 보이는 다각형을 생성하고, "가상"도넛의 중앙에 배치 된 흰색 중심 색과 색상 맵에서 보간 된 각 "정점"에 색상을 적용하는 것이 었습니다. (이중 버퍼링을 사용하여 깜박임 현상을 피할 수 있습니다.)

List<PointF> drawDonut(float angleA, float angleB, float width, int controlPointCount, float scaling, float centerX, float centerY) 
    { 
     List<PointF> points = new List<PointF>(); 
     if (controlPointCount < 2) 
     { 
      throw (new ArgumentOutOfRangeException("controlPointCount", "controlPointCount must be >1")); 
     } 
     if (width <= 0 || width > 100) 
     { 
      throw (new ArgumentOutOfRangeException("width", "width must be comprised between ]0:100]")); 
     } 

     List<float> angles = new List<float>(); 

     for (int i = 0; i < controlPointCount; i++) 
     { 
      angles.Add(angleA + (angleB - angleA) * (float)i/((float)controlPointCount - 1.0f)); 
     } 

     for (int i = 0; i < angles.Count; i++) 
     { 
      points.Add(new PointF((float)Math.Cos(angles[i]) * scaling + centerX, (float)Math.Sin(angles[i]) * scaling + centerY)); 
     } 
     for (int i = 0; i < angles.Count; i++) 
     { 
      points.Add(new PointF(((100.0f - width)/100.0f * (float)Math.Cos(angles[angles.Count - 1 - i])) * scaling + centerX, ((100.0f - width)/100.0f * (float)Math.Sin(angles[angles.Count - 1 - i])) * scaling + centerY)); 
     } 

     return points; 
    } 


    private List<Color> pieColor(Color[] MainColors, float[] mainStops, float[] stops) 
    { 
     List<Color> resultColors = new List<Color>(); 
     int index = 0; 
     float percent; 

     if (MainColors.Length != mainStops.Length) 
     { 
      throw new Exception("number of MainColors and mainStops must be the same"); 
     } 


     if (MainColors.Length < 2) 
     { 
      for (int i = 0; i < stops.Length; i++) 
      { 
       resultColors.Add((MainColors.Length == 1) ? MainColors[0] : Color.White); 
      } 
     } 
     else 
     { 
      for (int i = 0; i < stops.Length; i++) 
      { 
       index = Array.FindIndex(mainStops, x => x > stops[i]); 
       if (index == 0) 
       { 
        resultColors.Add(MainColors[0]); 
       } 
       else 
       { 
        if (index == -1) 
        { 
         resultColors.Add(MainColors.Last()); 
        } 
        else 
        { 
         percent = (stops[i] - mainStops[index - 1])/(mainStops[index] - mainStops[index - 1]) * 100f; 
         resultColors.Add(alphaBlend(MainColors[index - 1], MainColors[index], percent)); 
        } 
       } 
      } 
     } 

     return resultColors; 
    } 

    private Color alphaBlend(Color color1, Color color2, float percent) 
    { 

     byte R = (byte)(((float)color1.R * (100f - percent)/100f) + ((float)color2.R * (percent)/100f)); 
     byte G = (byte)(((float)color1.G * (100f - percent)/100f) + ((float)color2.G * (percent)/100f)); 
     byte B = (byte)(((float)color1.B * (100f - percent)/100f) + ((float)color2.B * (percent)/100f)); 
     return Color.FromArgb(R, G, B); 
    } 

    private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     RectangleF rec = e.ClipRectangle; 
     float midx = rec.Width/2; 
     float midy = rec.Height/2; 
     float pieSize = (float)Math.Min(midx, midy) * 0.9f; 
     float pieWidth = 5f; 
     float angleA = -225; 
     float angleB = 45; 
     int nstops = (int)(Math.Abs(angleA - angleB)/5 + 1); 
     float[] stops; 

     stops = new float[nstops]; 

     for (int i = 0; i < stops.Length; i++) 
     { 
      stops[i] = i * 100f/(stops.Length - 1); 
     } 

     List<PointF> myDonut = drawDonut(angleA * (float)Math.PI/180f, angleB * (float)Math.PI/180f, pieWidth, nstops, pieSize, midx, midy); 

     List<Color> myColors = pieColor(new Color[] { Color.Red, Color.Yellow, Color.Green, Color.Cyan, Color.Blue, Color.Magenta, Color.Red }, 
             new float[] { 0.0f, 100f/6f, 200f/6f, 300f/6f, 400f/6f, 500f/6f, 600f/6f }, 
             stops); 

     Color[] myPieColor = new Color[myDonut.Count]; 

     for (int i = 0; i < (myPieColor.Length/2); i++) 
     { 
      myPieColor[i] = myColors[i]; 
      myPieColor[myPieColor.Length - i - 1] = myColors[i]; 
     } 

     GraphicsPath gp = new GraphicsPath(); 
     gp.AddLines(myDonut.ToArray()); 
     e.Graphics.SmoothingMode = SmoothingMode.HighQuality; 
     using (PathGradientBrush b = new PathGradientBrush(gp)) 
     { 
      b.CenterPoint = new PointF(midx, midy); 
      b.CenterColor = Color.White; 
      b.SurroundColors = myPieColor; 

      e.Graphics.FillPath(b, gp); 

     } 
    } 
}