我试图绘制一条可以分成不同段的行(在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)
轻松解决您需要以矢量形式表示您的开始和结束
开始+(结束 - 开始)* n,其中n是[0..1]
由于您未在此处使用向量,因此需要单独拆分x和y
你的起始位置是start
,等于n = 0,你的最终位置(第五段)是end
,相当于n = 1.中间的每个位置都是n
的一小部分。
现在你需要绘制5行,我们将使用上面的公式
每个都有不同的颜色
答案 1 :(得分:0)
如果已连接分段,则可以将整个数字表示为点数组。第一点连接到第二点,第二点到第三点等等。
如果您需要Color
,那么您可以将其作为单独的数组,或者作为 segment 类型的一部分(这使得更有意义,您需要的更多参数)。
根据您的要求,在您的情况下,以某种方式定义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
是一项微不足道的任务,不会在此处发布。
答案 2 :(得分: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)));
}
}
}
}