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

namespace WaferAdjust
{
    /// <summary>
    /// 二维坐标旋转计算器（支持自定义坐标系方向）
    /// </summary>
    public class Rotation2D
    {
        #region 正向旋转：求旋转后的坐标

        /// <summary>
        /// 点A绕点B逆时针旋转指定角度（角度制）
        /// </summary>
        /// <param name="ax">点A的X坐标</param>
        /// <param name="ay">点A的Y坐标</param>
        /// <param name="bx">旋转中心B的X坐标</param>
        /// <param name="by">旋转中心B的Y坐标</param>
        /// <param name="angleDegrees">旋转角度（角度制，逆时针）</param>
        /// <param name="isRight">X轴正方向是否向右（默认true）</param>
        /// <param name="isUp">Y轴正方向是否向上（默认true）</param>
        /// <returns>旋转后的点A'坐标 (x', y')</returns>
        public static (double x, double y) RotatePointDegrees(
            double ax, double ay,
            double bx, double by,
            double angleDegrees,
            bool isRight = true,
            bool isUp = true)
        {
            return RotatePointRadians(ax, ay, bx, by,
                DegreesToRadians(angleDegrees), isRight, isUp);
        }

        /// <summary>
        /// 点A绕点B逆时针旋转指定角度（弧度制）
        /// </summary>
        /// <param name="ax">点A的X坐标</param>
        /// <param name="ay">点A的Y坐标</param>
        /// <param name="bx">旋转中心B的X坐标</param>
        /// <param name="by">旋转中心B的Y坐标</param>
        /// <param name="angleRadians">旋转角度（弧度制，逆时针）</param>
        /// <param name="isRight">X轴正方向是否向右（默认true）</param>
        /// <param name="isUp">Y轴正方向是否向上（默认true）</param>
        /// <returns>旋转后的点A'坐标 (x', y')</returns>
        public static (double x, double y) RotatePointRadians(
            double ax, double ay,
            double bx, double by,
            double angleRadians,
            bool isRight = true,
            bool isUp = true)
        {
            // 1. 转换为标准数学坐标系（向右为正，向上为正）
            double mathAx = isRight ? ax : -ax;
            double mathAy = isUp ? ay : -ay;
            double mathBx = isRight ? bx : -bx;
            double mathBy = isUp ? by : -by;

            // 2. 在标准坐标系中执行旋转
            double cosR = Math.Cos(angleRadians);
            double sinR = Math.Sin(angleRadians);

            double dx = mathAx - mathBx;
            double dy = mathAy - mathBy;

            double rotatedDx = dx * cosR - dy * sinR;
            double rotatedDy = dx * sinR + dy * cosR;

            double mathNewX = mathBx + rotatedDx;
            double mathNewY = mathBy + rotatedDy;

            // 3. 转换回用户指定的坐标系
            double outputX = isRight ? mathNewX : -mathNewX;
            double outputY = isUp ? mathNewY : -mathNewY;

            return (outputX, outputY);
        }

        #endregion

        #region 反向旋转：求旋转前的原始坐标

        /// <summary>
        /// 已知旋转后的点A'，求绕点B逆时针旋转前的原始点A（角度制）
        /// </summary>
        /// <param name="rotatedX">旋转后的点A'的X坐标</param>
        /// <param name="rotatedY">旋转后的点A'的Y坐标</param>
        /// <param name="bx">旋转中心B的X坐标</param>
        /// <param name="by">旋转中心B的Y坐标</param>
        /// <param name="angleDegrees">旋转角度（角度制，逆时针）</param>
        /// <param name="isRight">X轴正方向是否向右（默认true）</param>
        /// <param name="isUp">Y轴正方向是否向上（默认true）</param>
        /// <returns>原始的未旋转点A坐标 (x, y)</returns>
        public static (double x, double y) GetOriginalPointDegrees(
            double rotatedX, double rotatedY,
            double bx, double by,
            double angleDegrees,
            bool isRight = true,
            bool isUp = true)
        {
            return GetOriginalPointRadians(rotatedX, rotatedY, bx, by,
                DegreesToRadians(angleDegrees), isRight, isUp);
        }

        /// <summary>
        /// 已知旋转后的点A'，求绕点B逆时针旋转前的原始点A（弧度制）
        /// </summary>
        /// <param name="rotatedX">旋转后的点A'的X坐标</param>
        /// <param name="rotatedY">旋转后的点A'的Y坐标</param>
        /// <param name="bx">旋转中心B的X坐标</param>
        /// <param name="by">旋转中心B的Y坐标</param>
        /// <param name="angleRadians">旋转角度（弧度制，逆时针）</param>
        /// <param name="isRight">X轴正方向是否向右（默认true）</param>
        /// <param name="isUp">Y轴正方向是否向上（默认true）</param>
        /// <returns>原始的未旋转点A坐标 (x, y)</returns>
        public static (double x, double y) GetOriginalPointRadians(
            double rotatedX, double rotatedY,
            double bx, double by,
            double angleRadians,
            bool isRight = true,
            bool isUp = true)
        {
            // 1. 转换为标准数学坐标系
            double mathRotatedX = isRight ? rotatedX : -rotatedX;
            double mathRotatedY = isUp ? rotatedY : -rotatedY;
            double mathBx = isRight ? bx : -bx;
            double mathBy = isUp ? by : -by;

            // 2. 在标准坐标系中执行反向旋转
            double cosR = Math.Cos(angleRadians);
            double sinR = Math.Sin(angleRadians);

            double dx = mathRotatedX - mathBx;
            double dy = mathRotatedY - mathBy;

            // 反向旋转（相当于顺时针旋转）
            double originalDx = dx * cosR + dy * sinR;
            double originalDy = -dx * sinR + dy * cosR;

            double mathOriginalX = mathBx + originalDx;
            double mathOriginalY = mathBy + originalDy;

            // 3. 转换回用户指定的坐标系
            double outputX = isRight ? mathOriginalX : -mathOriginalX;
            double outputY = isUp ? mathOriginalY : -mathOriginalY;

            return (outputX, outputY);
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 角度转弧度
        /// </summary>
        private static double DegreesToRadians(double degrees)
        {
            return degrees * Math.PI / 180.0;
        }

        /// <summary>
        /// 弧度转角度（公共方法，供外部使用）
        /// </summary>
        public static double RadiansToDegrees(double radians)
        {
            return radians * 180.0 / Math.PI;
        }

        #endregion
    }

}
