"""
@Project : game_algorithm
@File : utils.py
@Author: wangjingbo
@Date: 2024/12/5 8:38
"""
import math
from typing import Sequence

XYZ_KEYS = ['current_x', 'current_y', 'current_z']


class Constant:
    """常数设置"""
    # 归一化常数
    SPEED = 1000
    DISTANCE = 200000
    X = 200000
    Y = 200000
    Z = 15000
    ANGLE = 360
    RADAR_GAIN = 100
    RADAR_POWER = 100000
    LON = 180
    LAT = 90
    ALT = 15000
    HEAD = 360  # 待确认
    PITCH = 90  # 待确认
    ROLL = 180  # 待确认
    RADAR_MAX_RANGE = 200
    RADAR_MIN_RANGE = 10
    DISTURB_FREQUENCY = 13000000000
    AIR_RANGE_MAX = 100

    KTS_TO_KM = 1.852  # 海理转公理系数
    EARTH_RADIUS = 6371.393  # 地球半径
    PI = 3.1415926
    degree2radian = PI / 180.0


def get_dis(own_position: Sequence[float], target_position: Sequence[float]) -> float:
    """计算两点距离
    :param own_position: 点1
    :param target_position: 点2
    :return: float, 两点距离
    """
    square = 0
    for pos1, pos2 in zip(own_position, target_position):
        square += (pos1 - pos2) ** 2
    return math.sqrt(square)


def get_dis_by_latlon(geopoint1: Sequence[float], geopoint2: Sequence[float]) -> float:
    """求地面两点的水平距离   Haversine公式
    :param geopoint1: tuple, (lat, lon), 例：(40.9, 140.0)
    :param geopoint2: tuple, (lat, lon), 例：(40.9, 142.0)
    :return: float, KM
    """
    lat1 = geopoint1[0] * Constant.degree2radian
    lon1 = geopoint1[1] * Constant.degree2radian
    lat2 = geopoint2[0] * Constant.degree2radian
    lon2 = geopoint2[1] * Constant.degree2radian

    difference = lat1 - lat2
    mdifference = lon1 - lon2
    distance = 2 * math.asin(math.sqrt(math.pow(math.sin(difference / 2), 2)
                                       + math.cos(lat1) * math.cos(lat2)
                                       * math.pow(math.sin(mdifference / 2), 2)))
    distance = distance * Constant.EARTH_RADIUS / 1000
    return distance


def get_direct_angle(own_position: Sequence[float], target_position: Sequence[float], own_angle: float = 0.) -> float:
    """获取两飞机之间的夹角, 以own_plane为视角来基准
    :param own_position: 本飞机的x,y坐标，输入为元组(x,y)
    :param target_position: 目标飞机的x,y坐标，输入为元组(x,y)
    :param own_angle: 本飞机的方向角
    :return: 两飞机的夹角
    """
    x = target_position[0] - own_position[0]
    y = target_position[1] - own_position[1]
    temp = math.atan2(y, x) / math.pi * 180
    angle = (temp + 360) % 360
    angle = angle - own_angle
    if angle > 180:
        angle = angle - 360
    elif angle < -180:
        angle = angle + 360
    return angle
