unity中三维数学

向量相减,向量相加
在这里插入图片描述
如上图a-b为c, a+b为d —> 在unity中相加相减后向量起点为加减向量公共起点
向量与数的乘与除 —> 模长的缩放
向量与向量的乘与除 —>1.点乘Dot:[x1,y1,z1][x1,y2,z2] = x1x2+y1y2+z1x2
参与点乘运算的向量标准化后,结果为夹角的 cos 值,几何意义Dot(a,b) = |a|
|b|*cos(a,b),只能看[0,180]之间,不能看出顺/逆时针,顺/逆时针须用叉乘
2.叉乘Cross:两个矢量的叉积产生第三矢量,该矢量垂直于两个输入矢量。结果的幅度等于两个输入的幅度相乘,然后乘以输入之间角度的正弦值。您可以使用“左手规则”确定结果向量的方向。
叉乘

 //计算向量长度
 Vector3 pos = transform.position;
 float m2 = pos.magnitude;
 
//计算向量方向(单位向量)
Vector3 pos = transform.position;
Vector3 n1 = pos / pos.magnitude;  //自己计算:向量/模场
Vector3 n2 = pos.normalized;        // normalized属性为单位向量

 public float angle;
//向量
private void Demo08()
    {
        //向量   + - 向量
        //向量   *  / 数
        //向量 (点乘Dot)  (叉乘Cross) 向量
        //
        //参与点乘运算的向量标准化后,结果为夹角的 cos 值
        float dot = Vector3.Dot(t1.position.normalized, t2.position.normalized);
        angle = Mathf.Acos(dot) * Mathf.Rad2Deg;
        //if (angle > 30)//比较角度
        if (dot < 0.866f)//比较cos值
        {
            //如果夹角大于30度则
        }
        Vector3 cross = Vector3.Cross(t1.position, t2.position);
        if (cross.y <0)   //cross的y小于0则角度为逆时针,否则为顺时针
        {
            angle = 360 - angle;
        }

    }

弧度与角度

    private void Demo04()
    { 
        // f1角度=>f2 弧度: 弧度=角度数*PI/180   
        float f1 = 50;
        float f2 = f1 * Mathf.PI / 180;
        float f3 = f1 * Mathf.Deg2Rad;
        // Mathf.Rad2Deg  弧度  --->  角度 
        //Mathf.Deg2Rad   角度 ---> 弧度
    }

三角函数:根据一边一角求另一边

 Mathf.Sin(x * Mathf.Deg2Rad)    输入弧度返回sin的值范围[-1,1]
Mathf.Cos(x * Mathf.Deg2Rad)
Mathf.Tan(x * Mathf.Deg2Rad)	

反三角函数:根据两边求角

 Mathf.Asin(0.5f)    输入浮点数值返回值对应的sin角度
Mathf.Acos(0.5f )
Mathf.Atan(0.5f)	

三角/反三角函数例子:

         //已知:角度x  边长 a
         //计算:边长 c
        float x = 50;
        float a = 10;
        float c = a / Mathf.Sin(x * Mathf.Deg2Rad);

        //已知:边长 a  c
        //计算:角度angle
        float angle = Mathf.Asin(a / c) * Mathf.Rad2Deg;

自身坐标 —> 世界坐标

    private void Demo06()
    { 
    	//返回自身坐标系前方10m的世界坐标系
        Vector3 worldPos = transform.TransformPoint(0, 0, 10); 
        Debug.DrawLine(this.transform.position, worldPos);  
    }

    //练习计算:前右方30度  10米处世界坐标 
    private void Demo07()
    { 
        Vector3 localPos =  new Vector3
                                        (
                                            10 * Mathf.Sin(30 * Mathf.Deg2Rad), 
                                            0, 
                                            10 * Mathf.Cos(30 * Mathf.Deg2Rad)
                                        );
        Vector3 worldPos = transform.TransformPoint(localPos);
        Debug.DrawLine(transform.position, worldPos);
    }

向量Vector的API

//因为 position 是属性,所以返回数据副本,直接修改z无效。所以编译错误。
 //transform.position.z = 1;

//方案1:
//复制(数据)
Vector3 pos = transform.position;
pos.z = 1;//如果仅仅修改位置的副本,物体位置不会发生改变
transform.position = pos;

//方案2: 
transform.position = new Vector3(transform.position.x, transform.position.y, 1);


//Vector3.Distance(位置1,位置2)        实际调用(位置1 - 位置2).模长 
//建议  (位置1 - 位置2).模长平方  sqrMagnitude


        Vector3 norm = t1.position;
        计算垂直向量
        //Vector3.OrthoNormalize(ref norm, ref tangent, ref binNormal);

        //计算t1物体在地面上的投影
        Vector3 project = Vector3.ProjectOnPlane(norm, Vector3.up);
        Debug.DrawLine(Vector3.zero, norm);
        Debug.DrawLine(Vector3.zero, project,Color.red);

        //计算反射向量:Vector3.Reflect 

    //移动类API
            //由快到慢      无限接近目标点
            //起点改变    终点、比例不变
            transform.position =Vector3.Lerp(transform.position, new Vector3(0, 0, 10), 0.1f);

            //匀速移动     无限接近目标点 
            transform.position =Vector3.MoveTowards(transform.position, new Vector3(0, 0, 10), 0.1f);

            //平滑阻尼
            transform.position =Vector3.SmoothDamp(transform.position, new Vector3(0, 0, 10), ref currentSpeed, 2);

	//变速运动
   	     public AnimationCurve curve  	 //曲线编辑器
            x += Time.deltaTime / time; //time=1  1S到终点 2 2s到终点
            //由快到慢      无限接近目标点
            //起点 、终点 不变     比例改变
            Vector3 begin = Vector3.zero;
            //transform.position =
            //    Vector3.Lerp(begin, new Vector3(0, 0, 10), curve.Evaluate(x));  //限制y超过
            transform.position =
                Vector3.LerpUnclamped(begin, new Vector3(0, 0, 10), curve.Evaluate(x));//不限制y超过

欧拉角:
x,z绕自身坐标系旋转,y绕世界坐标系y轴旋转
当延x轴旋转90°时,自身z与世界y重合,会造成万向节死锁.

transform.eulerAngles = new Vector3(10, 10, 0);     //赋值
transform.eulerAngles += new Vector3(1, 0, 0);  	//绕x轴转
transform.eulerAngles += Vector3.up;		//绕y轴
transform.eulerAngles += Vector3.forward;	//绕z轴

四元数:
四元数用于表示旋转。
它们结构紧凑,不受万向节锁定的影响,。Unity内部使用四元数来表示所有旋转.
四元数旋转均延自身旋转

四元数的表示
        //物体沿Y轴旋转50度
        Vector3 axis = Vector3.up;
        float rad = 50 * Mathf.Deg2Rad;
        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);
	transform.rotation = qt;
	//等同于调用Quaternion.Euler(0, 50, 0)
        transform.rotation = Quaternion.Euler(0, 50, 0);

transform.rotation *= Quaternion.Euler(1, 0, 0);		 //沿X轴旋转
//transform.Rotate(1, 0, 0); //Rotate通过四元数实现
transform.rotation *= Quaternion.Euler(0, 1, 0);		//沿Y轴旋转
transform.rotation *= Quaternion.Euler(0, 0, 1);		//沿Z轴旋转

四元数与向量相乘

四元数左乘向量:表示将该向量旋转四元数对应的角度
两个四元数与向量累乘:将向量连续旋转
//计算物体右前方30度10m处坐标
        Vector3 worldPos =
            transform.position + Quaternion.Euler(0, 30, 0) * transform.rotation * new Vector3(0, 0, 10);


四元数Quaternion的API

	//获取四元数
        Quaternion qt = transform.rotation;
        //1. 四元数  -->  欧拉角
        Vector3 euler = qt.eulerAngles;
        
        //2.欧拉角 --> 四元数
        Quaternion qt02 = Quaternion.Euler(0, 90, 0);
        
        //3.轴 / 角 旋转
        //transform.rotation = Quaternion.AngleAxis(30, Vector3.up);
        //transform.localRotation = Quaternion.AngleAxis(30, Vector3.up);  
    
        //4. 注视旋转
        //Quaternion dir = Quaternion.LookRotation(target.position - transform.position);
        //transform.rotation = dir;
        //transform.LookAt(target.position);

        //5.Lerp 插值旋转  由快到慢
        //transform.rotation = Quaternion.Lerp(transform.rotation, dir, 0.1f);

        //6.RotateTowards    匀速旋转
        //transform.rotation = Quaternion.RotateTowards(transform.rotation, dir, 0.1f);
        //Quaternion dir = Quaternion.Euler(0, 180, 0);
        //transform.rotation = Quaternion.Lerp(transform.rotation, dir, 0.005f);
        
        7. 四元数计算角度差
        //if (Quaternion.Angle(transform.rotation, dir) < 30)
        //    transform.rotation = dir;
        
        //8. X轴注视旋转
        transform.rotation = Quaternion.FromToRotation(Vector3.right, target.position - transform.position);

切点探测
计算P1,P2两点

	GameObject playerGO  = GameObject.FindWithTag("Player");
	playerTF = playerGO.transform;
	radius = playerGO.GetComponent<CapsuleCollider>().radius;

    public void CalaculateTangent()
    {
        Vector3 playerToExplosion = transform.position - playerTF.position;
        Vector3 playerToExplosionRadius = playerToExplosion.normalized * radius;
        float angle = Mathf.Acos(radius / playerToExplosion.magnitude) * Mathf.Rad2Deg;
        rightTangent =playerTF .position + Quaternion.Euler(0, angle, 0) * playerToExplosionRadius;
        leftTangent = playerTF.position + Quaternion.Euler(0, -angle, 0) * playerToExplosionRadius;
    }

    //**************测试**************
    private void Update()
    {
        CalaculateTangent();
        Debug.DrawLine(transform.position, leftTangent);
        Debug.DrawLine(transform.position, rightTangent);
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值