2014-01-22 5 views
0

Я пытаюсь нарисовать линию, которая может быть разбита на разные сегменты (в C# winforms).Рисование одной строки в разных цветах

Каждый сегмент будет иметь другой цвет, а также отображать на нем название.

Что я сделал прямо сейчас:

int startXPosition = 100; 
int startYPosition = 50; 
int numSegment = 5; 
int endXPosition = startXPosition; 
int endYPosition = this.Height/numSegment; 

Pen blackPen = new Pen(Color.Black, 5); 
e.Graphics.DrawLine(blackPen, new  Point(startXPosition, startYPosition), new  Point(endXPosition, endYPosition)); 

Это позволит мне нарисовать базовую линию на высоте виде в/5 (число сегмента) с использованием черного цвета.

Как продолжить отсюда, чтобы я мог провести остаток сегмента (4), в котором он будет иметь разный цвет?

Как я могу сделать это таким образом, что мне не нужно определять цвет, и код может автоматически назначать цвет для каждого другого сегмента?

+0

Разделить линию на части и нарисовать разным цветом –

ответ

0

Ну это может быть легко решено с помощью линейной алгебры (http://en.wikipedia.org/wiki/Linear_algebra)

Вы должны представить свое начало и конец в векторной форме в терминах

старт + (окончание - старт) * п, где п [0..1]

Как вы не используете векторы здесь вам нужно будет разделить й и у отдельно

Ваша начальная позиция равна start, которая равна n = 0, ваше конечное положение (пятого сегмента) равно end, что эквивалентно n = 1. Каждая позиция в промежутке составляет от n.

Теперь вам нужно сделать 5 строк, где мы будем использовать формулу выше

  1. Дро от п = 0 до п = 1/5
  2. Розыгрыш от п = 1/5 п = 2/5
  3. дро из п = 2/5 п = 3/5
  4. ..
  5. извлечь из п = 4/5 п = 5/5 (= 1)

Каждый с другим цветом

0

Если сегменты подключены, вы можете представить целое число фигурой в виде массива точек. Первая точка подключена к второму, второй к третьей и т.д.

Если вам нужно иметь Color «S, то вы можете иметь его как отдельный массив, или как часть сегмента типа (что делает более смысл сделать, тем больше параметров вам нужно).

В соответствии с вашими требованиями, достаточно в вашем случае, чтобы определить массив Color-х и линию как-то (возможно, используя y=kx+b выражение или запуск/конечная точка). Затем, когда вы рисуете, вы можете разделить линию в сегментах (используя формулы геометрии) и нарисовать каждый со своим цветом.

К примеру,

Color[] colors = new Color[] {Color.Red, Color.Black, Color.Green, Color.Blue, Color.Purple}; 
var k = 1; 
var b = 0; // y = x, diagonal line 

for(int i = 0; i < colors.Lengh; i++) 
{ 
    // calculate line coords 
    var y1 = this.Height/colors.Length * i; 
    var x1 = (y1 - b)/k; // x = (y - b)/k 
    var y2 = this.Height/colors.Length * (i + 1); 
    var x2 = (y2 - b)/k; 

    using(var pen = new Pen(colors[i])) 
     e.Graphics.DrawLine(pen, (int)x1, (int)y1, (int)x2, (int)y2); 
} 

Заметим, что это не точно, потому что вы должны использовать ClientRectangle уменьшается на 1 балл (и не образуют Height). В противном случае вы нарисуете на неклиент (это не проблема, но вы ничего не увидите).

Это простая задача получить k и b для заданной начальной/конечной точки линии, не отправляя ее здесь.

0

Это должно сделать для вас, я комментирую код, который мог бы лучше всего, не стесняйтесь задавать вопросы о том, что я сделал.

using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.Data; 
    using System.Drawing; 
    using System.Linq; 
    using System.Text; 
    using System.Windows.Forms; 

    namespace WindowsFormsApplication1 
    { 
     public partial class Form1 : Form 
     { 
      Bitmap buffer; //used to draw the lines and txt on first then make the Forms  Background image = buffer 
      public Form1() 
      { 
       InitializeComponent(); 
       //set the buffer to the same size as the form 
       buffer = new Bitmap(Width, Height); 

       //calls the method below 
       DrawLines(100,50,5,Graphics.FromImage(buffer)); 

       //sets the background image to = buffer 
      BackgroundImage = buffer; 

     } 

     public void DrawLines(int startX, int startY, int segments, Graphics g) 
     { 
      // this needs to be looked at since it pushes the lines off the screen 
      //perhaps you need to indicate a total line length then use it here instead of this.Height 

      //int TotalLength=500; 
      //int segmentLength = TotalLength/segments; 

      int segmentLength=this.Height/segments; 

      //I have created a array containing 5 Colors, this way I can reference them from within the For Loop below 
      //You can use whichever colors you wish 

      Color[] Colors = new Color[] { Color.Black, Color.Red,Color.Orange,Color.Yellow,Color.Green }; 

      //Loop through each of the segments 

      for (int y = 0; y < segments; y++) 
      { 
       //the using statements ensures your new p is disposed of properly when you are finished. You could also use 
       // Pens.Red, or Pens.Black, which do not need to be disposed of instead of creating a new one 
       using (Pen p= new Pen(Colors[y])) 
        g.DrawLine(p,new Point(startX,startY+(y*segmentLength)),new Point(startX,startY+((y+1)*segmentLength))); 
       //same thing for Pens also applies to Brush... Brushes.Red, Brushes.Black etc... 
       using (Brush b = new SolidBrush(Colors[y])) 
        g.DrawString(Colors[y].Name, Font, b, new Point(startX + 5, startY + (y * segmentLength) + (segmentLength/2))); 
      } 
     } 
    } 
} 
Смежные вопросы