关于带角度的箭头


好早之前写的代码,拿来冒傻气,带角度的箭头,即根据直线的斜率生成360的箭头,这里记录下之前的一些心得


根据斜率做角度会出现两种情况,如下图

 斜率大于角度,或者小于角度

位置会出现四种情况





角度情况做判断就可以了,后面的位置情况变化,可以做矩阵Transform,即按照斜率做角度变化即可,现在连html5都支持Transform,所以写起来没什么难度,我之前写的代码比较早了,没有使用矩阵变换,所以做了四次判断,属于不好的方法
下次会更新带有矩阵变换的办法


注意斜率的求法为 Math.Atan((Y2-Y1)/(X2-X1))

public static class GsrAlex
{
/*
 * ///////////////////////////////////////
 * ///////////////////////////////////////
 * ///////////////////////////////////////
 * 转载注明出处 gsralex.blog.163.com//
 * ///////////////////////////////////////
 * ///////////////////////////////////////
 * ///////////////////////////////////////
 * / <summary>
 * / 获取箭头所在的点
 * / </summary>
 * / <param name="startPoint">线段的起始点</param>
 * / <param name="endPoint">线段的结束点</param>
 * / <param name="gradientAngle">斜率</param>
 * / <param name="arrowAngle">箭头的角度</param>
 * / <param name="arrowSize">箭头的长度</param>
 * / <returns></returns>
 */
    public static List<Point> GetGsrAlexAngleArrow( Point startPoint, Point endPoint, double gradientAngle, double arrowAngle, double arrowSize )
    {
        double    angle;
        double    upPointX    = 0;
        double    upPointY    = 0;
        double    downPointX    = 0;
        double    downPointY    = 0;

        gradientAngle = Math.Abs( gradientAngle );

        if ( startPoint.Y < endPoint.Y )
        {
            if ( startPoint.X < endPoint.X )
            {
                if ( 0.5 * Math.PI - gradientAngle > arrowAngle )
                {
                    angle        = 0.5 * Math.PI - gradientAngle - arrowAngle;
                    upPointX    = endPoint.X - arrowSize * Math.Sin( angle );


                    upPointY = endPoint.Y - arrowSize * Math.Cos( angle );
                }else  {
                    angle        = gradientAngle + arrowAngle - 0.5 * Math.PI;
                    upPointX    = endPoint.X + arrowSize * Math.Sin( angle );


                    upPointY = endPoint.Y - arrowSize * Math.Cos( angle );
                }


                if ( gradientAngle > arrowAngle )
                {
                    angle        = gradientAngle - arrowAngle;
                    downPointX    = endPoint.X - arrowSize * Math.Cos( angle );


                    downPointY = endPoint.Y - arrowSize * Math.Sin( angle );
                }else  {
                    angle        = arrowAngle - gradientAngle;
                    downPointX    = endPoint.X - arrowSize * Math.Cos( angle );


                    downPointY = endPoint.Y + arrowSize * Math.Sin( angle );
                }
            }else  {
                if ( 0.5 * Math.PI - gradientAngle > arrowAngle )
                {
                    angle        = 0.5 * Math.PI - gradientAngle - arrowAngle;
                    upPointX    = endPoint.X + arrowSize * Math.Sin( angle );


                    upPointY = endPoint.Y - arrowSize * Math.Cos( angle );
                }else  {
                    angle        = arrowAngle - (0.5 * Math.PI - gradientAngle);
                    upPointX    = endPoint.X - arrowSize * Math.Sin( angle );


                    upPointY = endPoint.Y - arrowSize * Math.Cos( angle );
                }

                if ( gradientAngle > arrowAngle )
                {
                    angle        = gradientAngle - arrowAngle;
                    downPointX    = endPoint.X + arrowSize * Math.Cos( angle );


                    downPointY = endPoint.Y - arrowSize * Math.Sin( angle );
                }else  {
                    angle        = arrowAngle - gradientAngle;
                    downPointX    = endPoint.X + arrowSize * Math.Cos( angle );


                    downPointY = endPoint.Y + arrowSize * Math.Sin( angle );
                }
            }
        }else  {
            if ( startPoint.X < endPoint.X )
            {
                if ( gradientAngle > arrowAngle )
                {
                    angle        = gradientAngle - arrowAngle;
                    upPointX    = endPoint.X - arrowSize * Math.Cos( angle );


                    upPointY = endPoint.Y + arrowSize * Math.Sin( angle );
                }else  {
                    angle        = arrowAngle - gradientAngle;
                    upPointX    = endPoint.X - arrowSize * Math.Cos( angle );


                    upPointY = endPoint.Y - arrowSize * Math.Sin( angle );
                }

                if ( 0.5 * Math.PI - gradientAngle > arrowAngle )
                {
                    angle        = 0.5 * Math.PI - gradientAngle - arrowAngle;
                    downPointX    = endPoint.X - arrowSize * Math.Sin( angle );


                    downPointY = endPoint.Y + arrowSize * Math.Cos( angle );
                }else  {
                    angle        = arrowAngle - (0.5 * Math.PI - gradientAngle);
                    downPointX    = endPoint.X + arrowSize * Math.Sin( angle );


                    downPointY = endPoint.Y + arrowSize * Math.Cos( angle );
                }
            }else  {
                if ( gradientAngle > arrowAngle )
                {
                    angle        = gradientAngle - arrowAngle;
                    upPointX    = endPoint.X + arrowSize * Math.Cos( angle );


                    upPointY = endPoint.Y + arrowSize * Math.Sin( angle );
                }else  {
                    angle        = arrowAngle - gradientAngle;
                    upPointX    = endPoint.X + arrowSize * Math.Cos( angle );


                    upPointY = endPoint.Y - arrowSize * Math.Sin( angle );
                }

                if ( 0.5 * Math.PI - gradientAngle > arrowAngle )
                {
                    angle        = 0.5 * Math.PI - gradientAngle - arrowAngle;
                    downPointX    = endPoint.X + arrowSize * Math.Sin( angle );


                    downPointY = endPoint.Y + arrowSize * Math.Cos( angle );
                }else  {
                    angle        = arrowAngle - (0.5 * Math.PI - gradientAngle);
                    downPointX    = endPoint.X + arrowSize * Math.Sin( angle );


                    downPointY = endPoint.Y + arrowSize * Math.Cos( angle );
                }
            }
        }


        return(new List<Point>()
               {
                   new Point( upPointX, upPointY ), endPoint, new Point( downPointX, downPointY ), endPoint
               });
    }
}

 


2012年7月16日 郑州 天气:晴

欢迎转载,转载请注明出处 http://gsralex.blog.163.com/
posted @ 2012-07-16 15:53  gsralex  阅读(400)  评论(0编辑  收藏  举报