赶着时间又把那个箭头的绘制算法写了出来,但是由于是通过中心点来计算对应的另外一点,因此偏差比较大。
具体算法如下:
2 if (index < count - 1 )
3 {
4 float x1 = this .CenterPointF.X + (index) * this .XUnitWidth;
5 float y1 = this .CenterPointF.Y - Values[index] / this .YUnitValue * this .YUnitHeight;
6 float x2 = this .CenterPointF.X + (index + 1 ) * this .XUnitWidth;
7 float y2 = this .CenterPointF.Y - Values[index + 1 ] / this .YUnitValue * this .YUnitHeight;
8
9 // 画折线
10 graphics.DrawLine(Pens.Red,x1, y1, x2, y2);
11
12 // 画箭头
13 DrawArrowHead(graphics, new PointF(x1,y1), new PointF(x2,y2));
14 }
通过前后两点的X、Y坐标值进行比较,绘制的具体算法如下():
2 {
3 PointF p1 = beginPoint;
4 PointF p2 = endPoint;
5 float x = p2.X - p1.X;
6 float y = p2.Y - p1.Y;
7
8 if (x == 0 && y == 0 )
9 {
10 return ;
11 }
12
13 if (y == 0 )
14 {
15 PointF[] polygonPoints = {
16 new PointF(p2.X, p2.Y),
17 new PointF(p2.X + (x > 0 ?- this .ArrowLength: this .ArrowLength),p2.Y + this .ArrowWidth),
18 new PointF(p2.X + (x > 0 ?- this .ArrowLength: this .ArrowLength),p2.Y - this .ArrowWidth) };
19
20 DrawArrowHead(graphics, polygonPoints);
21 }
22 else if (x == 0 )
23 {
24 PointF[] polygonPoints = {
25 new PointF(p2.X, p2.Y),
26 new PointF(p2.X - this .ArrowWidth, p2.Y + (y < 0 ? this .ArrowLength: - this .ArrowLength)),
27 new PointF(p2.X + this .ArrowWidth, p2.Y + (y < 0 ? this .ArrowLength: - this .ArrowLength)) };
28
29 DrawArrowHead(graphics, polygonPoints);
30 }
31 else
32 {
33 double p3x;
34 double p3y;
35 double p4x;
36 double p4y;
37 double p5x;
38 double p5y;
39
40 p3x = Math.Round((p2.X - (p2.X - p1.X) * this .ArrowLength / Math.Sqrt((p2.Y - p1.Y) * (p2.Y - p1.Y) + (p2.X - p1.X) * (p2.X - p1.X))), 3 );
41 p3y = Math.Round((p2.Y - (p2.Y - p1.Y) * this .ArrowLength / Math.Sqrt((p2.Y - p1.Y) * (p2.Y - p1.Y) + (p2.X - p1.X) * (p2.X - p1.X))), 3 );
42 p4y = Math.Round((p3y + (p1.Y - p3y) * this .ArrowWidth / Math.Sqrt((p1.Y - p3y) * (p1.Y - p3y) + (p2.X - p3x) * (p2.X - p3x))), 3 );
43 p4x = Math.Round((p3x + (p2.X - p3x) * this .ArrowWidth / Math.Sqrt((p1.Y - p3y) * (p1.Y - p3y) + (p2.X - p3x) * (p2.X - p3x))), 3 );
44 p5x = Math.Round(p3x * 2 - p4x, 0 );
45 p5y = Math.Round(p3y * 2 - p4y, 0 );
46
47 PointF[] polygonPoints = {
48 new PointF((p2.X) , (p2.Y)),
49 new PointF( ( float )p4x , ( float )p4y),
50 new PointF( ( float )p5x , ( float )p5y)};
51
52 DrawArrowHead(graphics, polygonPoints);
53 }
54 }
关键点17-18行
17 new PointF(p2.X+(x>0?-this.ArrowLength:this.ArrowLength),p2.Y+this.ArrowWidth),
18 new PointF(p2.X+(x>0?-this.ArrowLength:this.ArrowLength),p2.Y-this.ArrowWidth) };
当y相等时,需要判断x的差值。
同理
26 new PointF(p2.X - this.ArrowWidth, p2.Y+(y<0?this.ArrowLength:-this.ArrowLength)),
27 new PointF(p2.X + this.ArrowWidth, p2.Y+(y<0?this.ArrowLength:-this.ArrowLength)) };
当x相等时,需要判断y的差值。
40 p3x = Math.Round((p2.X - (p2.X - p1.X) * this.ArrowLength / Math.Sqrt((p2.Y - p1.Y) * (p2.Y - p1.Y) + (p2.X - p1.X) * (p2.X - p1.X))), 3);
41 p3y = Math.Round((p2.Y - (p2.Y - p1.Y) * this.ArrowLength / Math.Sqrt((p2.Y - p1.Y) * (p2.Y - p1.Y) + (p2.X - p1.X) * (p2.X - p1.X))), 3);
42 p4y = Math.Round((p3y + (p1.Y - p3y) * this.ArrowWidth / Math.Sqrt((p1.Y - p3y) * (p1.Y - p3y) + (p2.X - p3x) * (p2.X - p3x))), 3);
43 p4x = Math.Round((p3x + (p2.X - p3x) * this.ArrowWidth / Math.Sqrt((p1.Y - p3y) * (p1.Y - p3y) + (p2.X - p3x) * (p2.X - p3x))), 3);
44 p5x = Math.Round(p3x * 2 - p4x, 0);
45 p5y = Math.Round(p3y * 2 - p4y, 0);
数学方式通过坐标值找出其他的2个点。
纯粹的数学计算,误差比较大。本人想到过用角度来计算,但是公式都忘得差不多了,得哪天找点资料看看才行。
显示的效果如下:(图一)
(图2)
估计通过角度来算的话,误差会比较少。这个当角度太大了的,误差越来越大,算法还有待提高。