using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CanFly.Canvas.Helper
{
    public static class PointHelper
    {
        public static Point ToPoint(this PointF pf)
        {
            return new Point((int)pf.X, (int)pf.Y);
        }

        /// <summary>
        /// 将相对于控件的坐标转换为相对于图像的坐标
        /// </summary>
        /// <param name="p">控件中指定点的点位坐标,坐标原点为控件左上角</param>
        /// <returns>该点以图像坐标系为基准的坐标值,坐标原点为图像左上角</returns>
        public static PointF ToImageCoordinate(this Point p, Matrix m)
        {
            PointF pf = new PointF(p.X, p.Y);
            return ToImageCoordinate(pf, m);
        }

        /// <summary>
        /// 将相对于控件的坐标转换为相对于图像的坐标
        /// </summary>
        /// <param name="p">控件中指定点的点位坐标,坐标原点为控件左上角</param>
        /// <returns>该点以图像坐标系为基准的坐标值,坐标原点为图像左上角</returns>
        public static PointF ToImageCoordinate(this PointF p, Matrix m)
        {
            PointF[] ps = new PointF[] { p };
            Matrix invertMatrix = m.Clone();
            //想要从旧空间到新空间的逆变换,所以我们需要对这个矩阵求逆
            invertMatrix.Invert();
            invertMatrix.TransformPoints(ps);
            return ps[0];
        }

        /// <summary>
        /// 将相对于图像的坐标转换为相对于控件坐标系
        /// </summary>
        /// <param name="p">图像中指定点的点位坐标,坐标原点为图像左上角</param>
        /// <returns>该点以空间坐标系为基准的坐标值,坐标原点为空间坐左上角</returns>
        public static PointF ToControlCoordinate(this PointF p, Matrix m)
        {
            PointF[] ps = new PointF[] { p };
            m.TransformPoints(ps);
            return ps[0];
        }




        public static float Distance(PointF p1, PointF p2)
        {
            return (float)Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
        }

        public static float DistanceToLine(PointF point, PointF start, PointF end)
        {
            float lineLengthSquared = DistanceSquared(start, end);
            if (lineLengthSquared == 0)
            {
                return Distance(point, start); // 线段的两个端点重合
            }

            float t = ((point.X - start.X) * (end.X - start.X) + (point.Y - start.Y) * (end.Y - start.Y)) / lineLengthSquared;
            t = Math.Clamp(t, 0, 1); // 限制 t 在 [0, 1] 范围内

            PointF projection = new PointF(
                start.X + t * (end.X - start.X),
                start.Y + t * (end.Y - start.Y));

            return Distance(point, projection);
        }


        public static float DistanceSquared(PointF p1, PointF p2)
        {
            return (float)(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
        }

    }
}