月份信息二维坐标图绘制---(绘制箭头算法)续

     赶着时间又把那个箭头的绘制算法写了出来,但是由于是通过中心点来计算对应的另外一点,因此偏差比较大。

     具体算法如下:

复制代码
 1  //画折线、箭头
 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坐标值进行比较,绘制的具体算法如下():

复制代码
 1 private void DrawArrowHead(Graphics graphics, PointF beginPoint, PointF endPoint)
 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)

 

    估计通过角度来算的话,误差会比较少。这个当角度太大了的,误差越来越大,算法还有待提高。

 

posted @   jasen.kin  阅读(2604)  评论(7编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示