• 如何在程序中画更好看的折线



    前言:



    做的程序需要两种线,一种是贝塞尔曲线,一种是折线,贝塞尔线比较简单,这里主要说折现,折现的折点不能出现的过多,否则会出现上面的情况



     
    一般这种折现会出现两种情况,我管着两种情况叫做凸点,和延伸点(ps:纯粹乱起),如上图所示,左上角的是“凸点”,右下角是“节省点”,折点过多主要是因为这两种原因造成的,我们可以对这两种折点进行优化,达到去除折点的作用,下面是一些代码片段

    <summary >
     合 并凸点 节 省 点
     </ summary>
     private void Combine()
     {
         允许控制点超过4
         if ( ControlPoints.Count <= 4 )
             return;
    
         List<ControlPoint> removeControlPointList = new List<ControlPoint>();
    
         ControlPoint lastControlPoint = ControlPoints.LastOrDefault();
         Point2Direct = GetDirect( lastControlPoint.Point, Point2 );
    
         List<int> leftList    = new List<int>();
         List<int> rightList    = new List<int>();
         List<int> upList    = new List<int>();
         List<int> downList    = new List<int>();
    
    
         int i = 0;
         foreach ( ControlPoint controlPoint in this.ControlPoints )
         {
             if ( i == 0 )
             {
             }else if ( i == ControlPoints.Count - 1 )
             {
             }else  {
                 switch ( controlPoint.BrokeLinePointDirect )
                 {
                 case BrokeLinePointDirect.Left:
                     {
                         leftList.Add( i );
                         break;
                     }
                 case BrokeLinePointDirect.Right:
                     {
                         rightList.Add( i );
                         break;
                     }
                 case BrokeLinePointDirect.Up:
                     {
                         upList.Add( i );
                         break;
                     }
                 case BrokeLinePointDirect.Down:
                     {
                         downList.Add( i );
                         break;
                     }
                 }
             }
    
             i++;
         }
    
    
         #region 注释
    
         #region  凸点
    
             /* 找到有效凸点 */
    
    
         if ( leftList.Count > 0 && rightList.Count > 0 )
         {
             foreach ( int leftItem in leftList )
             {
                 foreach ( int rightItem in rightList )
                 {
                                     /*有效凸点 */
                     if ( Math.Abs( leftItem - rightItem ) == 2 )
                     {
                         ControlPoint previousLeft    = ControlPoints[leftItem - 1];
                         ControlPoint left        = ControlPoints[leftItem];
                         ControlPoint previousRight    = ControlPoints[rightItem - 1];
                         ControlPoint right        = ControlPoints[rightItem];
    
                                             /* 非对称凸点 */
                         if ( previousLeft.Point.Y != right.Point.Y )
                         {
                             if ( leftItem < rightItem )
                             {
                                 ControlPoint addControlPoint = new ControlPoint();
                                 addControlPoint.Point            = new Point( right.Point.X, previousLeft.Point.Y );
                                 addControlPoint.BrokeLinePointDirect    = GetDirect( addControlPoint.Point, right.Point );
                                 this.ControlPoints.Insert( rightItem - 1, addControlPoint );
                                 removeControlPointList.Add( left );
                                 removeControlPointList.Add( previousRight );
                                 removeControlPointList.Add( right );
                             }else  {
                                 ControlPoint addControlPoint = new ControlPoint();
                                 addControlPoint.Point            = new Point( left.Point.X, previousRight.Point.Y );
                                 addControlPoint.BrokeLinePointDirect    = GetDirect( addControlPoint.Point, left.Point );
                                 this.ControlPoints.Insert( leftItem - 1, addControlPoint );
                                 removeControlPointList.Add( previousLeft );
                                 removeControlPointList.Add( left );
                                 removeControlPointList.Add( right );
                             }
                         }
                                             /* 对称凸点 */
                         else{
                             removeControlPointList.Add( ControlPoints[leftItem - 1] );
                             removeControlPointList.Add( ControlPoints[leftItem] );
                             removeControlPointList.Add( ControlPoints[rightItem - 1] );
                             removeControlPointList.Add( ControlPoints[rightItem] );
                         }
                     }
                 }
             }
         }
    
         if ( upList.Count > 0 && downList.Count > 0 )
         {
             foreach ( int upItem in upList )
             {
                 foreach ( int downItem in downList )
                 {
                                     /*有效凸点 */
                     if ( Math.Abs( upItem - downItem ) == 2 )
                     {
                         ControlPoint previousUp    = ControlPoints[upItem - 1];
                         ControlPoint up        = ControlPoints[upItem];
                         ControlPoint previousDown    = ControlPoints[downItem - 1];
                         ControlPoint down        = ControlPoints[downItem];
    
                                             /* 非对称凸点 */
                         if ( previousUp.Point.X != down.Point.X )
                         {
                             if ( upItem < downItem )
                             {
                                 ControlPoint addControlPoint = new ControlPoint();
                                 addControlPoint.Point            = new Point( down.Point.X, previousUp.Point.Y );
                                 addControlPoint.BrokeLinePointDirect    = GetDirect( addControlPoint.Point, down.Point );
                                 this.ControlPoints.Insert( downItem - 1, addControlPoint );
                                 removeControlPointList.Add( previousUp );
                                 removeControlPointList.Add( up );
                                 removeControlPointList.Add( previousDown );
                             }else  {
                                 ControlPoint addControlPoint = new ControlPoint();
                                 addControlPoint.Point            = new Point( up.Point.X, previousDown.Point.Y );
                                 addControlPoint.BrokeLinePointDirect    = GetDirect( addControlPoint.Point, up.Point );
                                 this.ControlPoints.Insert( upItem - 1, addControlPoint );
                                 removeControlPointList.Add( previousUp );
                                 removeControlPointList.Add( previousDown );
                                 removeControlPointList.Add( down );
                             }
                         }
                                             /* 对称凸点 */
                         else{
                             removeControlPointList.Add( ControlPoints[upItem - 1] );
                             removeControlPointList.Add( ControlPoints[upItem] );
                             removeControlPointList.Add( ControlPoints[downItem - 1] );
                             removeControlPointList.Add( ControlPoints[downItem] );
                         }
                     }
                 }
             }
         }
    
         foreach ( ControlPoint controlPoint in removeControlPointList )
         {
             this.ControlPoints.Remove( controlPoint );
         }
    
    
         #endregion
    
         #region  效节省点
    
             /* 找到有效省节点 */
    
         List<ControlPoint> removeControlList = new List<ControlPoint>();
    
         for ( int j = 0; j < leftList.Count; j++ )
         {
             for ( int k = 0; k < leftList.Count; k++ )
             {
                 if ( leftList[k] - leftList[j] == 2 )
                 {
                     ControlPoint jPreviousControlPoint    = ControlPoints[leftList[j] - 1];
                     ControlPoint jControlPoint        = ControlPoints[leftList[j]];
                     ControlPoint kPreviousControlPoint    = ControlPoints[leftList[k] - 1];
                     ControlPoint kControlPoint        = ControlPoints[leftList[k]];
    
    
                     ControlPoint addControlPoint = new ControlPoint();
                     addControlPoint.Point            = new Point( kControlPoint.Point.X, jControlPoint.Point.Y );
                     addControlPoint.BrokeLinePointDirect    = GetDirect( jPreviousControlPoint.Point, addControlPoint.Point );
                     this.ControlPoints.Insert( leftList[k - 1], addControlPoint );
                     removeControlList.Add( jControlPoint );
                     removeControlList.Add( kPreviousControlPoint );
                     removeControlList.Add( kControlPoint );
    
    
                                     /* 找到节省点 */
                 }
             }
         }
    
    
         for ( int j = 0; j < rightList.Count; j++ )
         {
             for ( int k = 0; k < rightList.Count; k++ )
             {
                 if ( rightList[k] - rightList[j] == 2 )
                 {
                     ControlPoint jPreviousControlPoint    = ControlPoints[rightList[j] - 1];
                     ControlPoint jControlPoint        = ControlPoints[rightList[j]];
                     ControlPoint kPreviousControlPoint    = ControlPoints[rightList[k] - 1];
                     ControlPoint kControlPoint        = ControlPoints[rightList[k]];
    
    
                     ControlPoint addControlPoint = new ControlPoint();
                     addControlPoint.Point            = new Point( kControlPoint.Point.X, jControlPoint.Point.Y );
                     addControlPoint.BrokeLinePointDirect    = GetDirect( jPreviousControlPoint.Point, addControlPoint.Point );
                     this.ControlPoints.Insert( rightList[k - 1], addControlPoint );
                     removeControlList.Add( jControlPoint );
                     removeControlList.Add( kPreviousControlPoint );
                     removeControlList.Add( kControlPoint );
    
    
                                     /* 找到节省点 */
                 }
             }
         }
    
    
         foreach ( ControlPoint controlPoint in removeControlList )
         {
             this.ControlPoints.Remove( controlPoint );
         }
    
         #endregion
    
         #endregion
     }

    经过一番调整,效果如下


    永远不会有超过4个的折点(我们判断是4个),去掉折点标注,效果不错,注意上面的方法,比如给每个折点加入一个enum,描述为现在折点的方向,才能进行优化。比如“凸点”的确认方式,就是先上 隔1个 再下 或者 先下 隔1个 再上 或者 先左 隔一个 再右 或者先右 隔一个 再左 ;节省点的确认方式,就是 先左 隔一个 还是左 或者 先右 隔一个 还是右 即可 上下不用判断 或者 判断上下也可以,不判断左右

    ps:可惜最后和要做的效果不符,所以推翻重做,发博文是因为博文太少了,来充数,呵呵,见笑

    后续:悲催周五做了一天的工作算是白做了,周六在家加班又改制了一个好的使用体验的,程序员就是悲催啊



    2012年7月28日 于郑州 天气:晴            晚上在家加班中。。。

      我要啦免费统计
    博客搬家从blog.163.com/gsralex 搬家到 www.cnblogs.com/gsralex
    博文全部为原创,谢绝一切转载
  • 相关阅读:
    PHP关于VC11,VC9,VC6以及Thread Safe和Non Thread Safe版本选择的问题
    团队展示
    测试与优化:设计模式的应用和初次尝试多线程
    结对编程,三年级混合运算
    一个大气又可爱的标题
    随笔
    C#操作word类文件
    TypeError: Object of type 'int32' is not JSON serializable ——已解决
    Error: UserWarning: Ignoring URL... 已解决
    tensorflow(二)----线程队列与io操作
  • 原文地址:https://www.cnblogs.com/gsralex/p/3538040.html
Copyright © 2020-2023  润新知