模拟重力Parabolic Motion

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

public class MissileAI : MonoBehaviour
{
    private Transform mTransform;
    public const float g = 2f;

    private GameObject target;
    public float speed = 2f;
    private float verticalSpeed;
    private Vector3 moveDirection;

    private float angleSpeed;
    private float angle;

    private bool isMove;

    public GameObject temp;
    private Transform selfChild;

    private GameObject explosionEffect;
    private void Awake()
    {
        explosionEffect = Resources.Load<GameObject> ("Effects/BigExplosionEffect");
    }
    public void SetInfo (GameObject targe)
    {
        selfChild = transform.GetChild (0);
        target = targe;
        isMove = true;
        float tmepDistance = Vector3.Distance (transform.position, target.transform.position);
        float tempTime = tmepDistance / speed;
        float riseTime, downTime;
        riseTime = downTime = tempTime / 2;
        verticalSpeed = g * riseTime;
        selfChild.LookAt (target.transform.position);

        float tempTan = verticalSpeed / speed;
        double hu = Mathf.Atan (tempTan);
        angle = (float)(180 / Mathf.PI * hu);
        transform.eulerAngles = new Vector3 (-angle, transform.eulerAngles.y, transform.eulerAngles.z);
        angleSpeed = angle / riseTime;

        moveDirection = target.transform.position - transform.position;
        time = 0;
        //Debug.Log("SetInfo:" + target.transform.position+"  transformPos"+transform.position);
    }
    private float time;
    void Update ()
    {
        if (GameManager.Instance.gameState != EGameState.Gaming) return;
        if (!isMove)
            return;
        if (transform.position.y < target.transform.position.y) {
            time = 0;
            isMove = false;
            //Debug.Log ("missiledestory");
            BattleController.Instance.selfBattlePeopleList.Remove (gameObject);
            GameObject explosion = Instantiate (explosionEffect);
            explosion.transform.parent = BattleController.Instance.generatorParent.transform;
            explosion.transform.localPosition = transform.localPosition;
            explosion.transform.localScale = Vector3.one;
            Damage ();
            Destroy (gameObject,0.1f);
            return;
        }
        selfChild.LookAt (target.transform.position);
        time += Time.deltaTime;
        float test = verticalSpeed - g * time;
        transform.Translate (moveDirection.normalized * speed * Time.deltaTime, Space.World);
        transform.Translate (Vector3.up * test * Time.deltaTime, Space.World);
        float testAngle = -angle + angleSpeed * time;
        transform.eulerAngles = new Vector3 (testAngle, transform.eulerAngles.y, transform.eulerAngles.z);
    }
    public float attackDistance;
    public string maskTarget;
    private int colsLength;
    private HeroAI targetHeroAI;
    private BunkerAI targetBunkerAI;
    void Damage ()
    {
        Collider [] cols = Physics.OverlapSphere (transform.position, attackDistance, 1 << LayerMask.NameToLayer (maskTarget));
        colsLength = cols.Length;
        if (colsLength <= 0) {
            return;
        } else {
            targetHeroAI = null;
            targetBunkerAI = null;

            for (int i = 0; i < colsLength; i++) {
                targetHeroAI = null;
                targetBunkerAI = null;
                targetHeroAI = cols [i].GetComponent<HeroAI> ();
                targetBunkerAI =cols [i].GetComponent<BunkerAI> ();
                if(targetHeroAI!=null)
                {
                    targetHeroAI.HP -= 100;
                    //bomb bomb bomb
                }
                else if(targetBunkerAI !=null)
                {
                    targetBunkerAI.HP -= 100;
                    //bomb bomb bomb
                }
            }

        }
    }
    //private void OnTriggerEnter(Collider other)
    //{
    //    if (other.transform.tag == "RealPlayer1")
    //    {
    //        mTransform.gameObject.SetActive(false);
    //        Debug.Log("OnCollisionEnterRealPlayer1");
    //    }
    //}
    //private void OnTriggerEnter (Collider col)
    //{
    //    //Debug.Log ("collision:");
    //    if (col.transform.name.Contains ("Fish")) {
            

    //    }
    //}

}
  
### 抛物线逼近算法的实现 抛物线逼近是一种用于优化问题的技术,通常通过拟合二次多项式来近似目标函数的行为。这种方法可以被用来加速梯度下降或其他数值优化技术中的收敛过程。 #### 基本原理 在许多情况下,目标函数可以通过局部区域内的二次多项式进行近似表示。假设当前迭代点 \( x_k \),我们可以构建一个二次模型: \[ f(x) \approx f(x_k) + g_k^T (x - x_k) + \frac{1}{2} (x - x_k)^T H_k (x - x_k), \] 其中 \( g_k \) 是梯度向量,\( H_k \) 是海森矩阵[^1]。如果能够找到使上述二次模型最小化的点,则可以用它作为下一步的候选解。 #### MATLAB 实现示例 下面是一个简单的 MATLAB 函数实现,展示如何利用抛物线逼近的思想求解一维最优化问题: ```matlab function [xmin, fmin] = parabolic_approximation(f, x0, tol) % 使用抛物线逼近法寻找单变量函数 f 的极小值 % % 输入参数: % f : 被优化的目标函数句柄 % x0 : 初始猜测点 % tol : 收敛容忍度 % % 输出参数: % xmin : 极小值对应的自变量位置 % fmin : 对应的函数值 max_iter = 100; % 设置最大迭代次数 iter = 0; h = 1e-4; % 小步长用于有限差分估计导数 while iter < max_iter % 计算当前点及其附近两点处的函数值 fx0 = f(x0); fx_plus_h = f(x0 + h); fx_minus_h = f(x0 - h); % 近似计算一阶和二阶导数 grad = (fx_plus_h - fx_minus_h) / (2 * h); % 数值梯度 hessian = (fx_plus_h - 2*fx0 + fx_minus_h) / (h^2); % 数值Hessian if abs(hessian) < eps || isnan(grad/hessian) disp('无法继续优化'); break; end % 更新规则基于二次模型的顶点公式 (-b/2a) step = -grad / hessian; % 如果更新幅度小于容忍度则停止 if abs(step) < tol break; end x0 = x0 + step; % 执行一步更新操作 iter = iter + 1; end xmin = x0; fmin = f(xmin); ``` 此代码片段展示了如何使用数值方法估算梯度和曲率信息,并据此调整搜索方向。注意这仅适用于简单的一维情况;多维扩展需要额外考虑维度间的相互作用项。 #### 结合 `fminunc` 的应用 当面对更高维度或者复杂形式的目标函数时,MATLAB 提供了内置工具如 `fminunc` 可以简化工作流程。正如提到过的那样,在调用此类高级接口之前需先编写自己的成本函数(Cost Function)。例如,如果我们希望解决如下非线性规划问题: \[ \text{Minimize } J(\theta)= (\theta_1-\sin(\pi))^2+(\cos(e^\theta)-\sqrt{\theta})^2, \] 那么相应的 costFunction 定义可能看起来像这样: ```matlab function [J, grad] = my_cost_function(theta) % 自定义代价函数及其梯度 if nargin == 1 && nargout > 1 % 当请求梯度时执行解析推导或自动微分 J = ... ; % 描述目标表达式的具体实现细节省略 grad = ... ; else % 单纯返回标量值的情况 J = ... ; end end ``` 随后只需传递适当初始化条件给 `fminunc` 并启动训练循环即可完成自动化寻优任务[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值