package com.njcn.gather.script.util;

/**
 * @author hongawen
 * @version 1.0
 * @data 2025/2/25 13:24
 */

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class ThreePhaseUnbalance {

    // 定义复数类
    public static class Complex {
        BigDecimal real; // 复数的实部
        BigDecimal imag; // 复数的虚部

        // 构造函数，初始化复数的实部和虚部
        public Complex(BigDecimal real, BigDecimal imag) {
            this.real = real;
            this.imag = imag;
        }

        // 复数加法
        public Complex add(Complex other) {
            return new Complex(this.real.add(other.real), this.imag.add(other.imag));
        }

        // 复数乘法
        public Complex multiply(Complex other) {
            BigDecimal real = this.real.multiply(other.real).subtract(this.imag.multiply(other.imag));
            BigDecimal imag = this.real.multiply(other.imag).add(this.imag.multiply(other.real));
            return new Complex(real, imag);
        }

        // 复数除以一个实数
        public Complex divide(BigDecimal divisor) {
            return new Complex(this.real.divide(divisor, MathContext.DECIMAL128),
                    this.imag.divide(divisor, MathContext.DECIMAL128));
        }

        // 计算复数的模（幅值）
        public BigDecimal magnitude() {
            return BigDecimal.valueOf(Math.sqrt(real.multiply(real).add(imag.multiply(imag)).doubleValue()));
        }
    }

    // 将幅值和角度（角度制）转换为复数
    public static Complex fromPolar(BigDecimal magnitude, BigDecimal angleDegrees) {
        double angleRadians = Math.toRadians(angleDegrees.doubleValue()); // 将角度转换为弧度
        BigDecimal real = magnitude.multiply(BigDecimal.valueOf(Math.cos(angleRadians))); // 计算实部
        BigDecimal imag = magnitude.multiply(BigDecimal.valueOf(Math.sin(angleRadians))); // 计算虚部
        return new Complex(real, imag);
    }

    // 计算三相电压的对称分量（零序、正序、负序）
    public static Complex[] calculateSymmetricalComponents(Complex va, Complex vb, Complex vc) {
        // 120度相位因子 a = e^(j120°) = -0.5 + j * sqrt(3)/2
        Complex a = new Complex(BigDecimal.valueOf(-0.5), BigDecimal.valueOf(Math.sqrt(3) / 2));
        // 240度相位因子 a^2 = e^(j240°) = -0.5 - j * sqrt(3)/2
        Complex a2 = a.multiply(a);

        // 零序分量 V0 = (Va + Vb + Vc) / 3
        Complex v0 = va.add(vb).add(vc).divide(BigDecimal.valueOf(3));

        // 正序分量 V1 = (Va + a * Vb + a^2 * Vc) / 3
        Complex v1 = va.add(a.multiply(vb)).add(a2.multiply(vc)).divide(BigDecimal.valueOf(3));

        // 负序分量 V2 = (Va + a^2 * Vb + a * Vc) / 3
        Complex v2 = va.add(a2.multiply(vb)).add(a.multiply(vc)).divide(BigDecimal.valueOf(3));

        // 返回零序、正序、负序分量
        return new Complex[]{v0, v1, v2};
    }

    // 计算三相电压的不平衡度
    public static void calculateUnbalance(Complex v0, Complex v1, Complex v2) {
        // 计算零序、正序、负序分量的幅值
        BigDecimal v0Mag = v0.magnitude(); // 零序分量幅值
        BigDecimal v1Mag = v1.magnitude(); // 正序分量幅值
        BigDecimal v2Mag = v2.magnitude(); // 负序分量幅值

        // 计算不平衡度
        BigDecimal zeroSequenceUnbalance = v1Mag.compareTo(BigDecimal.ZERO) != 0 ?
                v0Mag.divide(v1Mag, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;

        BigDecimal negativeSequenceUnbalance = v1Mag.compareTo(BigDecimal.ZERO) != 0 ?
                v2Mag.divide(v1Mag, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;

        BigDecimal positiveSequenceUnbalance = BigDecimal.valueOf(100); // 正序电压不平衡度通常为100%

        // 输出结果，保留2位小数
        System.out.printf("零序电压不平衡度: %.2f%%\n", zeroSequenceUnbalance.setScale(2, RoundingMode.HALF_UP).doubleValue());
        System.out.printf("负序电压不平衡度: %.2f%%\n", negativeSequenceUnbalance.setScale(2, RoundingMode.HALF_UP).doubleValue());
        System.out.printf("正序电压不平衡度: %.2f%%\n", positiveSequenceUnbalance.setScale(2, RoundingMode.HALF_UP).doubleValue());
    }

    /**
     * 负序电压不平衡度
     */
    public static double calculateUnbalance(double Ua0, double thetaA,
                                            double Ub0, double thetaB,
                                            double Uc0, double thetaC) {

        // 输入三相电压的幅值和相位角（角度制）
        BigDecimal vaMagnitude = new BigDecimal(Ua0);
        BigDecimal vaAngle = new BigDecimal(thetaA);

        BigDecimal vbMagnitude = new BigDecimal(Ub0);
        BigDecimal vbAngle = new BigDecimal(thetaB);

        BigDecimal vcMagnitude = new BigDecimal(Uc0);
        BigDecimal vcAngle = new BigDecimal(thetaC);

        // 将幅值和角度转换为复数
        Complex va = fromPolar(vaMagnitude, vaAngle);
        Complex vb = fromPolar(vbMagnitude, vbAngle);
        Complex vc = fromPolar(vcMagnitude, vcAngle);

        // 计算对称分量
        Complex[] symmetricalComponents = calculateSymmetricalComponents(va, vb, vc);
        Complex v1 = symmetricalComponents[1]; // 正序分量
        Complex v2 = symmetricalComponents[2]; // 负序分量

        // 计算零序、正序、负序分量的幅值
        BigDecimal v1Mag = v1.magnitude(); // 正序分量幅值
        BigDecimal v2Mag = v2.magnitude(); // 负序分量幅值


        BigDecimal negativeSequenceUnbalance = v1Mag.compareTo(BigDecimal.ZERO) != 0 ?
                v2Mag.divide(v1Mag, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;

        // 输出结果，保留2位小数
        return negativeSequenceUnbalance.setScale(2, RoundingMode.HALF_UP).doubleValue();
    }


    public static void main(String[] args) {

        // 输入三相电压的幅值和相位角（角度制）
        System.out.println("请输入A相电压的幅值（单位：V）：");
        BigDecimal vaMagnitude = new BigDecimal(57.74);
        System.out.println("请输入A相电压的相位角（单位：度）：");
        BigDecimal vaAngle = new BigDecimal(0);

        System.out.println("请输入B相电压的幅值（单位：V）：");
        BigDecimal vbMagnitude = new BigDecimal(57.74 * 0.9);
        System.out.println("请输入B相电压的相位角（单位：度）：");
        BigDecimal vbAngle = new BigDecimal(-122);

        System.out.println("请输入C相电压的幅值（单位：V）：");
        BigDecimal vcMagnitude = new BigDecimal(57.74);
        System.out.println("请输入C相电压的相位角（单位：度）：");
        BigDecimal vcAngle = new BigDecimal(118);

        // 将幅值和角度转换为复数
        Complex va = fromPolar(vaMagnitude, vaAngle);
        Complex vb = fromPolar(vbMagnitude, vbAngle);
        Complex vc = fromPolar(vcMagnitude, vcAngle);

        // 计算对称分量
        Complex[] symmetricalComponents = calculateSymmetricalComponents(va, vb, vc);
        Complex v0 = symmetricalComponents[0]; // 零序分量
        Complex v1 = symmetricalComponents[1]; // 正序分量
        Complex v2 = symmetricalComponents[2]; // 负序分量

        // 输出对称分量
        System.out.printf("零序分量: %.2f + j%.2f\n", v0.real.setScale(2, RoundingMode.HALF_UP).doubleValue(),
                v0.imag.setScale(2, RoundingMode.HALF_UP).doubleValue());
        System.out.printf("正序分量: %.2f + j%.2f\n", v1.real.setScale(2, RoundingMode.HALF_UP).doubleValue(),
                v1.imag.setScale(2, RoundingMode.HALF_UP).doubleValue());
        System.out.printf("负序分量: %.2f + j%.2f\n", v2.real.setScale(2, RoundingMode.HALF_UP).doubleValue(),
                v2.imag.setScale(2, RoundingMode.HALF_UP).doubleValue());

        // 计算并输出不平衡度
        calculateUnbalance(v0, v1, v2);

    }
}
