package com.imdroid.sideslope.bd;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 1.简化重心计算，选取和参考点最近的50%的点求均值
 */
public class FocusCalculator4 extends FocusCalculator1{
    final Logger logger = LoggerFactory.getLogger(FocusCalculator4.class);
    // b562算法相关：b562固定解的点、计算球心初始半径、迭代步长、最少点数

    public FocusCalculator4(){
        super();
        gravityMinCount = 80;
    }

    @Override
    public double[] resultB562(){
        try {
            if (pointList.size() >= gravityMinCount) {
                List<Point> selectPoints = new ArrayList<>();
                // 如果有参考点，则选取距离参考点最近的50%的点
                // 否则排序取中间50%
                if (referPoint != null && referPoint.length > 0) {
                    // 计算所有点位与变量之间的距离，并存入集合
                    for (double[] point : pointList) {
                        Point pointObj = new Point(point[0], point[1], point[2]);
                        pointObj.setXDistance(Math.abs(point[0] - referPoint[0])); // 设置该点到变量的水平距离
                        pointObj.setYDistance(Math.abs(point[1] - referPoint[1])); // 设置该点到变量的水平距离
                        pointObj.setZDistance(Math.abs(point[2] - referPoint[2])); // 设置该点到变量的垂直距离
                        selectPoints.add(pointObj); // 将点位加入集合
                    }
                    //分别对东北天排序
                    Collections.sort(selectPoints, Comparator.comparing(Point::getXDistance));//排序
                    List<Point> points = selectPoints.subList(0, selectPoints.size() / 2);
                    double[] focusX = focusPointObj(points);
                    Collections.sort(selectPoints, Comparator.comparing(Point::getYDistance));//排序
                    points = selectPoints.subList(0, selectPoints.size() / 2);
                    double[] focusY = focusPointObj(points);
                    Collections.sort(selectPoints, Comparator.comparing(Point::getZDistance));//排序
                    points = selectPoints.subList(0, selectPoints.size() / 2);
                    double[] focusZ = focusPointObj(points);
                    return new double[]{focusX[0], focusY[1], focusZ[2]};
                }
                else {
                    for (int i = pointList.size()/2; i < pointList.size(); i++) {
                        selectPoints.add(new Point(pointList.get(i)[0], pointList.get(i)[1], pointList.get(i)[2]));
                    }
                    // 求重心
                    double[] focus = focusPointObj(selectPoints);
                    return focus;
                }
            }
        }
        catch (Exception e){
            logger.error("error!",e);
            return null;
        }
        return resultB562Sub();
    }

    @Override
    public int getVer() {
        return 4;
    }

}
