圆与圆的顺(逆)时针切线向量(方向)

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

public class Circular : MonoBehaviour
{


    public GameObject TangentPrefab;

    private void Start()
    {
        Creat();
    }

    void Creat()
    {
        for (int i = 0; i < 361; i+=10)
        {

            Vector3 v = GetCircularPoint(this.transform.position, 50, i);
            GameObject go=GameObject.CreatePrimitive(PrimitiveType.Sphere);
            go.transform.position = v;
            go.transform.name = i.ToString();

            Vector3 v2 = ClockwiseTangent(v, i);

            GameObject go2 = Instantiate(TangentPrefab);
            go2.transform.position = v;
            go2.transform.LookAt(v2);

            go2.transform.name = i.ToString() + "_ClockwiseTangent";

        }
    }

    /*
     * 注意:计算圆上点的时候 与 计算切线点的时候 相差90°
     * 原理:没有想清楚(切线)
     * 正确性:不知道(切线)
     * 效果:看上去像是对的(切线)
     */

    /// <summary>
    /// 获取圆上的点_Local坐标
    /// </summary>
    /// <param name="origin"></param>
    /// <param name="radius"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    private Vector3 GetCircularPoint_Local(Transform origin, float radius, float angle)
    {
        float local = origin.localEulerAngles.y;
        float radians = ((angle - 90 - local) / 180f) * Mathf.PI;
        Vector3 v = new Vector3(Circular_X(origin.position.x, radius, radians), 0, Circular_Y(origin.position.z, radius, radians));
        return v;
    }

    /// <summary>
    /// 获取圆上点的切线(逆时针)_Local坐标
    /// </summary>
    /// <param name="origin"></param>
    /// <param name="point"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    private Vector3 AnticlockwiseTangent_Local(Transform origin, Vector3 point, float angle)
    {
        float local = origin.localEulerAngles.y;
        float radians = ((angle - local) / 180f) * Mathf.PI;
        Vector3 v = new Vector3(Mathf.Cos(radians), 0, Mathf.Sin(radians)) + point;
        return v - point;
    }

    /// <summary>
    /// 获取圆上点的切线(顺时针)_Local坐标
    /// </summary>
    /// <param name="origin"></param>
    /// <param name="point"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    private Vector3 ClockwiseTangent_Local(Transform origin, Vector3 point, float angle)
    {
        float local = origin.localEulerAngles.y;
        float radians = ((angle - local) / 180f) * Mathf.PI;
        Vector3 v = new Vector3(Mathf.Cos(radians), 0, Mathf.Sin(radians)) + point;
        return v - point;
    }

    /// <summary>
    /// 获取圆上的点
    /// </summary>
    /// <param name="origin"></param>
    /// <param name="radius"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    private Vector3 GetCircularPoint(Vector3 origin,float radius,float angle)
    {
        float radians = ((angle -90) / 180f) * Mathf.PI;
        Vector3 v = new Vector3(Circular_X(origin.x, radius, radians), 0, Circular_Y(origin.z, radius, radians));
        return v;
    }


    /// <summary>
    /// 获取圆上点的切线(顺时针)
    /// </summary>
    /// <param name="pos">圆上的点</param>
    /// <param name="angle">圆上点的角度</param>
    /// <returns></returns>
    private Vector3 ClockwiseTangent(Vector3 pos, float angle)
    {
    	float radians = ((angle) / 180f) * Mathf.PI;
        Vector3 v= new Vector3(-Mathf.Cos(radians), 0, -Mathf.Sin(radians)) + pos;
        return v - pos;
    }


    /// <summary>
    /// 获取圆上点的切线(逆时针)
    /// </summary>
    /// <param name="pos">圆上的点</param>
    /// <param name="angle">圆上点的角度</param>
    /// <returns></returns>
    private Vector3 AnticlockwiseTangent(Vector3 pos, float angle)
    {
        float radians = ((angle) / 180f) * Mathf.PI;
        Vector3 v= new Vector3(Mathf.Cos(radians), 0, Mathf.Sin(radians)) + pos;
        return v - pos;
    }


    /// <summary>
    /// 圆x坐标
    /// </summary>
    /// <param name="a">圆心x坐标</param>
    /// <param name="r">半径</param>
    /// <param name="angle">角度</param>
    /// <returns></returns>
    private float Circular_X(float a, float r, float radians)
    {
        return (a + r * Mathf.Cos(radians));
    }

    /// <summary>
    /// 圆y坐标
    /// </summary>
    /// <param name="b">圆心y坐标</param>
    /// <param name="r">半径</param>
    /// <param name="angle">角度</param>
    /// <returns></returns>
    private float Circular_Y(float b, float r, float radians)
    {
        return (b + r * Mathf.Sin(radians));
    }
	
	/// <summary>
    /// 获取角度[0,360]
    /// </summary>
    /// <param name="lhs"></param>
    /// <param name="rhs"></param>
    /// <returns></returns>
	private float GetAngle(Vector3 lhs, Vector3 rhs)
    {
       float angle = Vector3.Angle(lhs, rhs);
       Vector3 cross = Vector3.Cross(lhs, rhs);
        if (cross.y > 0)
        {
            angle = 180 + (180 - angle);
        }
        return angle;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值