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


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

         具体算法如下:

     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)

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

  • 相关阅读:
    Oracle 字符串转多行(REGEXP_SUBSTR)
    Word使用技巧总结
    VirtualBox配置安装入门(Linux连不上网络和设置共享文件夹)
    (vm/vb)虚拟机复制或者拷贝之后连不上网络怎么处理?
    Vmware共享文件夹安装设置方法(window与Linux使用共享文件夹)
    软删除和硬删除的处理方法
    banner小点点
    常用标签
    优雅批量删除redis匹配数据
    rabbitmq(三)- 交换机
  • 原文地址:https://www.cnblogs.com/jasenkin/p/graphic_drawing_arrow_head.html
Copyright © 2020-2023  润新知