﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 平面坐标坐标系转换工具，把非unity的坐标转换成unity的世界坐标
/// 适用于非unity坐标系的转换包括（位移、旋转、缩放（x与y轴等比例））
/// 经纬度转换也可以，只是精度不高（高纬度地区与低纬度地区 1纬度代表距离不一样）
/// </summary>
public class CoordinateConversionManager : MonoBehaviour
{
    private CoordinateAnchor point0;
    private CoordinateAnchor point1;

    private Vector3 point0InUnity;
    private Vector3 point1InUnity;

    private double scale;//两个坐标系的缩放比（）
    private float angle;//非unity坐标系的旋转角度（度）

    private float xTran;//非unity坐标系x轴相对位移
    private float yTran;//非unity坐标系y轴相对位移

    private void Reset()
    {
        if (this.transform.childCount > 0) return;
        //创建控制点
        for (var i = 0; i < 2; i++)
        {
            var obj = new GameObject("point_" + i);
            obj.AddComponent<CoordinateAnchor>();
            obj.transform.parent = this.transform;
        }
    }

    private void Start()
    {
        var child0 = this.transform.GetChild(0);
        if (child0 != null)
        {
            point0 = child0.GetComponent<CoordinateAnchor>();
            point0InUnity = child0.transform.position;
        }

        var child1 = this.transform.GetChild(1);
        if (child1 != null)
        {
            point1 = child1.GetComponent<CoordinateAnchor>();
            point1InUnity = child1.transform.position;
        }

        Vector2 v0 = new Vector2(point0InUnity.x - point1InUnity.x, point0InUnity.z - point1InUnity.z);
        Vector2 v1 = new Vector2((float)(point0.AssociativeX - point1.AssociativeX), (float)(point0.AssociativeY - point1.AssociativeY));
        //计算比例关系
        scale = v0.magnitude / v1.magnitude;
        //计算旋转关系
        angle = Vector2.SignedAngle(v1, v0);
        //计算位移关系
        xTran = GetOffset((float)point0.AssociativeX, (float)point0.AssociativeY).x - point0InUnity.x;
        yTran = GetOffset((float)point0.AssociativeX, (float)point0.AssociativeY).z - point0InUnity.z;
    }

    /// <summary>
    /// 计算两个坐标系的偏移(非unity坐标系原点在unity世界坐标系中的位置)
    /// </summary>
    /// <param name="e"></param>
    /// <param name="n"></param>
    /// <returns></returns>
    private Vector3 GetOffset(float e, float n)
    {
        e = e * (float)scale;
        n = n * (float)scale;
        float e1 = e * Mathf.Cos(Mathf.Deg2Rad * angle) - n * Mathf.Sin(Mathf.Deg2Rad * angle);
        float n1 = n * Mathf.Cos(Mathf.Deg2Rad * angle) + e * Mathf.Sin(Mathf.Deg2Rad * angle);
        return new Vector3(e1, 0, n1);
    }

    /// <summary>
    /// 获取其他坐标系坐标点在unity坐标系中的坐标
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public Vector3 GetUnityPosition(float x,float y)
    {
        x = x * (float)scale;
        y = y * (float)scale;
        float e1 = x * Mathf.Cos(Mathf.Deg2Rad * angle) - y * Mathf.Sin(Mathf.Deg2Rad * angle);
        float n1 = y * Mathf.Cos(Mathf.Deg2Rad * angle) + x * Mathf.Sin(Mathf.Deg2Rad * angle);
        return new Vector3(e1 - xTran, 0, n1 - yTran);
    }
}