Unity学习笔记 3D数学

21 篇文章 0 订阅

向量

大小

向量的模长
公式:Mathf.Sqrt(Mathf.Pow(T1.pos.x,2),Mathf.Pow(T1.pos.y,2),Mathf.Pow(T1.pos.z,2));
Api: T1.pos.magnitude;

方向

公式: V/|V|, 向量除于其模长,
T1.pos / Mathf.Sqrt(Mathf.Pow(T1.pos.x,2),Mathf.Pow(T1.pos.y,2),Mathf.Pow(T1.pos.z,2));
结果:一个向量除于一个float,得到的结果还是一个向量
Unity Api: T1.pos.normalized;

点乘

点乘结果与角度之间的关系
点乘结果与角度之间的关系

欧拉角

  • 使用三个角度来保存方位
  • X 与 Z 沿自身坐标系旋转,Y 轴沿世界坐标系旋转。
  • API: Vector3 eulerAngle = transform.eulerAngles;

四元素

公式:
//旋转轴
Vecter3 axis = Vecter3.up;//或者:tar.position-irg.position;
//旋转角度
float angle = 50;
//角度转弧度:

float rad = Mathf.Deg2Rad(angle);
Quaternion qt = new Quaternion();
qt.x = Mathf.Sin(rad/2)* axis.x;
qt.y = Mathf.Sin(rad/2)* axis.y;
qt.z=Mathf.Sin(rad/2)* axis.z;
qt.w=Mathf.Cos(rad/2);
this. transform. rotation = qt;

欧拉角转四元素API:
this. transform. rotation = Quaternion. Euler(0,50,0);

四元素转欧拉角API
Quaternion qt = transform. rotation;
Vector3 euler = qt.eulerAngles;

轴/角旋转:
Quaternion qt = Quaternion.AngleAxis(50, Vector3.up);//沿y轴旋转50度,这个轴可以是任意轴,两向量相减得到的方向也可。

注视旋转:
当前物体的z轴注视某个方向并沿其旋转
if(GuiLayout.Button(""){
Quaternion dir = Quaternion. LookRotation(tf.position - transform. position);
//差值旋转
Quaternion.Lerp ( transform. rotation,dir,0.1f);
}//从当前的z轴看向的方向慢慢转向dir所表示的方向。
//匀速旋转
Quaternion.RotateToWards ( transform. rotation,qt ,0.1f);

//通过判断两个四元素之间的角度来确定两个四元素是否足够接近
float angel = Quaternion. Angle( transform. rotation,qt );

//指定物体的轴旋转到某方向
transform. rotation = Quaternion. FromToRotation ( Vector3. right, dt.position - transform. position);

//
四元素相乘
两个四元素相乘达到组合旋转的效果
this. transform. rotation *= Quaternion.Euler(20,0,0);
//将一个物体沿自身的x轴旋转20度
四元素组合使用 *=
向量组合使用 +=
Quaternion qt = new Quaternion();
qt = Quarternion.Euler(0,20,0) * Quaternion.Euler(20,60,0);
等价于:qt = Quaternion.Euler(20,80,0);

Unity中访问四元素与欧拉角的api
四元素: transform. rotation ;
欧拉角: transform.eulerAngle;

四元素与欧拉角灵活使用以达到好用的同时又能避免万向节死锁
限制角度时使用欧拉角,无角度限制时使用四元素!

四元素与向量相乘,表示将该向量沿着四元素表示的角度旋转。例如:
Vector3 vet1 = Vector3. forward*10;
//世界坐标正前方十米
//将它沿着y轴旋转30度
Vector3 vet2 = Quaternion.Euler(0,30) * ver1;
//这个vet2就是旋转30度后该向量所在的位置

叉乘,结合点乘可知该物体所在的方向是在左边还是右边

#region  叉乘
    ///<summary>
    ///叉乘
    ///垂直与这两个向量构成的平面的向量
    ///</summary>    
    void Demo6(){
        //点乘
        float T1DotT2 = Vector3.Dot(T1.transform.position.normalized,T2.transform.position.normalized);
        //叉乘
        Vector3 T1CrossT2 = Vector3.Cross(T2.transform.position.normalized,T1.transform.position.normalized);
        Debug.LogFormat("T1 叉乘 T2 = {0}",T1CrossT2);
        //Mathf.Acos 弧度,需要转换成角度 Mathf.Rad2Deg
        float angle = Mathf.Acos(T1DotT2) * Mathf.Rad2Deg;
        if(T1CrossT2.y < 0){
            angle = 360 - angle;
        }
        Debug.LogFormat("T1 与 T2 的夹角为:{0}",angle);
        Debug.DrawLine(Vector3.zero,T1.transform.position,Color.red);
        Debug.DrawLine(Vector3.zero,T2.transform.position,Color.green);
        Debug.DrawLine(Vector3.zero,T1CrossT2.normalized * 5,Color.blue);
    }
    #endregion

计算切点

	public Transform T2;
    private string PlayTag = "Player";
    private float PlayerRadio;
    GameObject Player;
    // Start is called before the first frame update
    void Start()
    {
        Player = GameObject.FindGameObjectWithTag(PlayTag);
        CharacterController cctro = Player.GetComponent<CharacterController>();
        if (cctro!= null) PlayerRadio = cctro.radius;
    }
    void Update()
    {
      CalculateTangent();
        Debug.DrawLine(T2.transform.position,leftTangent);
        Debug.DrawLine(T2.transform.position,rightTangent);
	}
	#region  切点
    ///<summary>
    ///切点
    ///</summary>    
    private Vector3 leftTangent,rightTangent;
    void CalculateTangent(){
       Vector3 playerToExplosion = T2.transform.position - Player.transform.position;
       Vector3 PlayerToExplosionDirection = playerToExplosion.normalized;
       float angle = Mathf.Acos(PlayerRadio/playerToExplosion.magnitude) * Mathf.Rad2Deg;   
       leftTangent = Player.transform.position + Quaternion.Euler(0,-angle,0) *(PlayerToExplosionDirection * PlayerRadio);  
       rightTangent = Player.transform.position + Quaternion.Euler(0,angle,0) *(PlayerToExplosionDirection * PlayerRadio);  
    }
    #endregion

计算切点
画箭头

void Demo7(){
        //画箭身
        Vector3 arrow = T2.transform.position - T1.transform.position;
        float arrowLength = arrow.magnitude;    //箭身长度        

        //箭方向的反方向
        Vector3 arrowHead = arrow.normalized * -1;
        //箭头的长度
        Vector3 arrowHeadLength = arrowHead * Mathf.Clamp((arrowLength/10),0.3f,0.68f);
        //向左旋转
        Vector3 leftArrowHead  = T2.transform.position  + Quaternion.Euler(0,15,0) * arrowHeadLength;
        //向右旋转
        Vector3 rightArrowHead  = T2.transform.position + Quaternion.Euler(0,-15,0) * arrowHeadLength;
       //箭头封口处
        Vector3 arrowHead2 = T2.transform.position  + arrowHead * Mathf.Sin(30*Mathf.Deg2Rad) * (leftArrowHead -T2.transform.position).magnitude;
        
        Debug.DrawLine(T1.transform.position,T2.transform.position,Color.red);
        Debug.DrawLine(T2.transform.position,leftArrowHead,Color.red);
        Debug.DrawLine(T2.transform.position,rightArrowHead,Color.red);
        Debug.DrawLine(leftArrowHead,arrowHead2,Color.red);
        Debug.DrawLine(rightArrowHead,arrowHead2,Color.red);
    }
    #endregion

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值