c#绘图PointF的数学计算方法

c#绘图PointF的数学计算方法

 		static public bool Checkfloat(float f1, float f2, float span = 1)
        {
     
            float fspan = Math.Abs(f1 - f2);
            if (fspan <= span)
            {
     
                return true;
            }
            return false;
        }
        /// 
        /// 计算直线的长度
        /// 
        /// 直线起点
        /// 直线终点
        /// 
        static public double GetLineLength(PointF startPt, PointF endPt)
        {
     
            double distance = 0;
            if (startPt != null && endPt != null && startPt != endPt)
            {
     
                distance = (double)Math.Pow((Math.Pow((endPt.X - startPt.X), 2) + Math.Pow((endPt.Y - startPt.Y), 2)), 1.0 / 2);
            }
            return distance;
        }
        /// 
        /// 求线段夹角和交点
        /// 
        /// 直线1的起点
        /// 直线1的终点
        /// 直线2的起点
        /// 直线2的终点
        /// 线段是否延伸(true)
        /// 线段交点
        /// 
        static public float Caltwolineangle(PointF line1startpt, PointF line1endpt, PointF line2startpt, PointF line2endpt, bool extend, ref PointF CrossPt)
        {
     
            bool flag = true;
            if (line1startpt == null || line1endpt == null || line2startpt == null || line2endpt == null)
            {
     
                return 0.0f;
            }
            float fangle = Get2LineAngle(line1startpt, line1endpt, line2startpt, line2endpt);
            Get2LineCrossPt(line1startpt, line1endpt, line2startpt, line2endpt, flag, ref CrossPt);
            return fangle;
        }


        /// 
        /// 两条带方向直线夹角求取,范围[0,180],同向为0
        /// 
        /// 直线1的起点
        /// 直线1的终点
        /// 直线2的起点
        /// 直线2的终点
        /// 
        static public float Get2LineAngle(PointF line1startpt, PointF line1endpt, PointF line2startpt, PointF line2endpt)
        {
     
            double fangle = 0.0f;
            double angle1 = 0.0f;
            double angle2 = 0.0f;
            if (line1startpt == null || line1endpt == null || line2startpt == null || line2endpt == null)
            {
     
                return 0.0f;
            }
            angle1 = GetLineAngle(line1startpt, line1endpt);
            angle2 = GetLineAngle(line2startpt, line2endpt);
            if (Math.Abs(angle1 - angle2) > Math.PI)
            {
     
                fangle = 2 * Math.PI - Math.Abs(angle1 - angle2);
            }
            else
            {
     
                fangle = Math.Abs(angle1 - angle2);
            }
            return (float)fangle;
        }
        /// 
        /// 获取直线相对于X轴角度[0-360)
        /// 
        /// 直线起点
        /// 直线终点
        /// 
        static public float GetLineAngle(PointF startPt, PointF endPt)
        {
     
            double angle = 0;
            if (startPt == null || endPt == null)
            {
     
                return 0.0f;
            }

            if (Checkfloat(endPt.X, startPt.X))
            {
     
                if (endPt.Y > startPt.Y)
                {
     
                    angle = 3 * Math.PI / 2;
                }
                else
                {
     
                    angle = Math.PI / 2;
                }
            }
            else if (endPt.X > startPt.X)
            {
     
                double k2 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
                angle = -Math.Atan(k2);
                if (angle < 0)
                {
     
                    angle += 2 * Math.PI;
                }
            }
            else
            {
     
                float k2 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
                angle = -Math.Atan(k2);
                angle += Math.PI;
            }
            return (float)angle;
        }

        /// 
        /// 两条直线交点的求取,直线平行返回false
        /// 
        /// 直线1的起点
        /// 直线1的终点
        /// 直线2的起点
        /// 直线2的终点
        /// 直线交点
        /// 
        static public bool Get2LineCrossPt(PointF line1startpt, PointF line1endpt, PointF line2startpt, PointF line2endpt, bool extend, ref PointF CrossPt)
        {
     
            CrossPt = new PointF(0, 0);
            if (line1startpt == null || line1endpt == null || line2startpt == null || line2endpt == null)
            {
     
                return false;
            }
            if ((line1endpt.X != line1startpt.X) || (line2endpt.X != line2startpt.X))
            {
     
                if ((line1endpt.X == line1startpt.X) && (line2endpt.X != line2startpt.X))
                {
     
                    float k2 = (line2endpt.Y - line2startpt.Y) / (line2endpt.X - line2startpt.X);
                    CrossPt.X = line1startpt.X;
                    CrossPt.Y = k2 * CrossPt.X - k2 * line2startpt.X + line2startpt.Y;
                }
                else if ((line1endpt.X != line1startpt.X) && (line2endpt.X == line2startpt.X))
                {
     
                    float k1 = (line1endpt.Y - line1startpt.Y) / (line1endpt.X - line1startpt.X);
                    CrossPt.X = line2startpt.X;
                    CrossPt.Y = k1 * CrossPt.X - k1 * line1startpt.X + line1startpt.Y;
                }
                else
                {
     
                    float k1 = (line1endpt.Y - line1startpt.Y) / (line1endpt.X - line1startpt.X);
                    float k2 = (line2endpt.Y - line2startpt.Y) / (line2endpt.X - line2startpt.X);
                    if (k1 == k2)
                    {
     
                        return false;
                    }
                    CrossPt.X = (k1 * line1startpt.X - k2 * line2startpt.X - line1startpt.Y + line2startpt.Y) / (k1 - k2);
                    CrossPt.Y = k1 * CrossPt.X - k1 * line1startpt.X + line1startpt.Y;
                }
                //两直线不扩展
                #region
                if (extend != true)
                {
     
                    float a1 = Math.Abs(GetLineAngle(line1endpt, CrossPt) - GetLineAngle(CrossPt, line1startpt));
                    float a2 = Math.Abs(GetLineAngle(line2endpt, CrossPt) - GetLineAngle(CrossPt, line2startpt));
                    if (a1 < 1E-3 && a2 < 1E-3)
                    {
     
                        return true;
                    }
                    else
                    {
     
                        return false;
                    }
                }
                #endregion
                //直线扩展
                #region
                else
                {
     
                    return true;
                }
                #endregion
            }
            else
            {
     
                return false;
            }
        }

        /// 
        /// 点到直线距离
        /// 
        /// 直线起点
        /// 直线终点
        /// 任意点
        /// 
        static public float GetLengthPtToLine(PointF startPt, PointF endPt, PointF Pt)
        {
     
            double length = 0;
            //点在直线上
            if (startPt == null || endPt == null || Pt == null)
            {
     
                return 0.0f;
            }
            #region
            if (Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) < 1E-3 || Math.Abs(Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) - Math.PI) < 1E-3)
            {
     

            }
            #endregion
            //点在直线外
            #region
            else
            {
     
                double a = GetLineLength(startPt, Pt);
                double b = GetLineLength(endPt, Pt);
                double c = GetLineLength(startPt, endPt);
                double p = (a + b + c) / 2;
                if (c == 0)
                {
     
                    return 0;
                }
                length = (double)Math.Pow(p * (p - a) * (p - b) * (p - c), 1.0 / 2) * 2 / c;
            }
            #endregion
            return (float)length;
        }
        /// 
        /// 点到线段最近的点
        /// 
        /// 直线起点
        /// 直线终点
        /// 任意点
        /// 线段是否延伸
        /// 
        static public PointF GetClosePt(PointF startPt, PointF endPt, PointF Pt, bool extend)
        {
     
            PointF NearPt = new PointF();
            //点在直线上(线段内部)
            if (startPt == null || endPt == null || Pt == null)
            {
     
                return NearPt;
            }
            #region
            if (Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) < 1E-3)
            {
     
                NearPt = Pt;
            }
            #endregion
            //点在直线上(线段外部)
            #region
            else if (Math.Abs(Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) - Math.PI) < 1E-3)
            {
     
                if (GetLineLength(endPt, Pt) < GetLineLength(startPt, Pt))
                {
     
                    if (extend == true)
                    {
     
                        NearPt = Pt;
                    }
                    else
                    {
     
                        NearPt = endPt;
                    }
                }
                else
                {
     
                    if (extend == true)
                    {
     
                        NearPt = Pt;
                    }
                    else
                    {
     
                        NearPt = startPt;
                    }
                }
            }
            #endregion
            //点不在直线上
            #region
            else
            {
     
                //计算垂足
                #region
                float spanx = endPt.X - startPt.X;
                float spany = endPt.Y - startPt.Y;
                if (spanx <= 1 && spanx >= -1)
                {
     
                    endPt.X = startPt.X;
                }
                if (spany <= 1 && spany >= -1)
                {
     
                    endPt.Y = startPt.Y;
                }
                if (endPt.X != startPt.X)
                {
     
                    if (endPt.Y != startPt.Y)
                    {
     
                        double k1 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
                        double k2 = -1 / k1;
                        NearPt.X = (float)((Pt.Y - startPt.Y - k2 * Pt.X + k1 * startPt.X) / (k1 - k2));
                        NearPt.Y = (float)(k2 * NearPt.X + Pt.Y - k2 * Pt.X);
                    }
                    else
                    {
     
                        NearPt.X = Pt.X;
                        NearPt.Y = endPt.Y;
                    }
                }
                else
                {
     
                    NearPt.X = endPt.X;
                    NearPt.Y = Pt.Y;
                }
                #endregion
                //垂足不在线段内,最近点为端点,延伸后是垂足
                #region
                if (Math.Abs(GetLineAngle(endPt, NearPt) - GetLineAngle(NearPt, startPt)) < 1E-3)
                {
     

                }
                else
                {
     
                    if (extend == false)
                    {
     
                        if (GetLineLength(endPt, NearPt) < GetLineLength(startPt, NearPt))
                        {
     
                            NearPt = endPt;
                        }
                        else
                        {
     
                            NearPt = startPt;
                        }
                    }
                }
                #endregion
            }
            #endregion
            return NearPt;
        }
        /// 
        /// 点到线段最近的点,并返回长度
        /// 
        /// 直线起点
        /// 直线终点
        /// 任意点
        /// 线段是否延伸
        /// 返回长度
        /// 
        static public PointF GetClosePt(PointF startPt, PointF endPt, PointF Pt, bool extend, ref float distance)
        {
     
            PointF NearPt = new PointF();
            if (startPt == null || endPt == null || Pt == null)
            {
     
                return NearPt;
            }

            //点在直线上(线段内部)
            #region
            if (Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) < 1E-3)
            {
     
                NearPt = Pt;
            }
            #endregion
            //点在直线上(线段外部)
            #region
            else if (Math.Abs(Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) - Math.PI) < 1E-3)
            {
     
                if (GetLineLength(endPt, Pt) < GetLineLength(startPt, Pt))
                {
     
                    if (extend == true)
                    {
     
                        NearPt = Pt;
                    }
                    else
                    {
     
                        NearPt = endPt;
                    }
                }
                else
                {
     
                    if (extend == true)
                    {
     
                        NearPt = Pt;
                    }
                    else
                    {
     
                        NearPt = startPt;
                    }
                }
            }
            #endregion
            //点不在直线上
            #region
            else
            {
     
                //计算垂足
                #region
                float spanx = endPt.X - startPt.X;
                float spany = endPt.Y - startPt.Y;
                if (spanx <= 1 && spanx >= -1)
                {
     
                    endPt.X = startPt.X;
                }
                if (spany <= 1 && spany >= -1)
                {
     
                    endPt.Y = startPt.Y;
                }

                if (endPt.X != startPt.X)
                {
     
                    if (endPt.Y != startPt.Y)
                    {
     
                        double k1 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
                        double k2 = -1 / k1;
                        NearPt.X = (float)((Pt.Y - startPt.Y - k2 * Pt.X + k1 * startPt.X) / (k1 - k2));
                        NearPt.Y = (float)(k2 * NearPt.X + Pt.Y - k2 * Pt.X);
                    }
                    else
                    {
     
                        NearPt.X = Pt.X;
                        NearPt.Y = endPt.Y;
                    }
                }
                else
                {
     
                    NearPt.X = endPt.X;
                    NearPt.Y = Pt.Y;
                }
                #endregion
                //垂足不在线段内,最近点为端点,延伸后是垂足
                #region
                if (Math.Abs(GetLineAngle(endPt, NearPt) - GetLineAngle(NearPt, startPt)) < 1E-3)
                {
     

                }
                else
                {
     
                    if (extend == false)
                    {
     
                        if (GetLineLength(endPt, NearPt) < GetLineLength(startPt, NearPt))
                        {
     
                            NearPt = endPt;
                        }
                        else
                        {
     
                            NearPt = startPt;
                        }
                    }
                }
                #endregion
            }
            #endregion
            distance = (float)GetLineLength(NearPt, Pt);
            return NearPt;

        }

        /// 
        /// 获取两个点的中心点
        /// 
        /// 开始点
        /// 种植点
        /// 返回点
        public static PointF GetPointCenter(PointF star, PointF end)
        {
     
            return new PointF((star.X + end.X) / 2, (star.Y + end.Y) / 2);
        }


        /// 
        /// 得到两个点的中间点坐标
        /// 
        /// 
        /// 
        /// 
        public static PointF Get2PointCenter(PointF one, PointF two)
        {
     
            PointF centerPT = new PointF();
            if (one != null && two != null)
            {
     
                centerPT = new PointF((one.X + two.X) / 2, (one.Y + two.Y) / 2);
            }
            return centerPT;
        }


        /// 
        /// 已知一条直线,一个长度,求距离开始点长度的,直线上的坐标
        /// 
        /// 
        /// 
        /// 
        /// 
        public static PointF Get_PointMovePoint(PointF startPT, PointF endPT, double length)
        {
     
            var ang =GetLineAngle(startPT, endPT);
            var a = length * Math.Cos(ang);
            var b = -length * Math.Sin(ang);
            var newPT = new PointF((Single)(startPT.X + a), (Single)(startPT.Y + b));
            return newPT;
        }


        public static float GetMin(float x, float y)
        {
     
            if (x < y)
                return x;
            else
                return y;
        }

        public static float GetMax(float x, float y)
        {
     
            if (x > y)
                return x;
            else
                return y;
        }

        /// 
        /// 判断点是否在线段上
        /// 
        /// 
        /// 
        /// 
        /// 
        public static bool Get_PointInLine(PointF P1, PointF P2, PointF Q)
        {
     
            var k1 = (Q.X - P1.X) * (P2.Y - P1.Y);
            var k2 = (P2.X - P1.X) * (Q.Y - P1.Y);

            if ((int)(k1 / 10) == (int)(k2 / 10))
            {
     
                if ((GetMin(P1.X, P2.X) <= Q.X && Q.X <= GetMax(P1.X, P2.X)) && GetMin(P1.Y, P2.Y) <= Q.Y && Q.Y <= GetMax(P1.Y, P2.Y))
                {
     
                    return true;
                }
                else
                {
     
                    return false;
                }
            }
            else
            {
     
                return false;
            }

        }

        /// 
        /// PointF转化为Point
        /// 
        /// 
        /// 
        public static List<Point> PointFToPoint(List<PointF> pths)
        {
     
            List<Point> ps = new List<Point>();
            foreach (var item in pths)
            {
     
                ps.Add(new Point((int)item.X, (int)item.Y));
            }
            return ps;

        }

        /// 
        /// 检测点是否在一定范围内
        /// 
        /// 
        /// 
        /// 
        public static bool TestPointInGraph(List<PointF> allpt, PointF needpt)
        {
     
            var pts = PointFToPoint(allpt);
            pts.Add(pts[0]);
            using (GraphicsPath path = new GraphicsPath())
            {
     
                path.AddLines(pts.ToArray());

                Region reg = new Region(path);
                if (reg.IsVisible(needpt))
                {
     
                    return true;
                }
            }
            return false;
        }

你可能感兴趣的:(c#)