3D螺旋导弹算法

3 篇文章 0 订阅
2 篇文章 0 订阅

我们在做射击游戏的时候发射的一种导弹,它延着子弹正方向螺旋的前进

子弹从点A(x1,y1,z1) 向点B(x2,y2,z2)  如何螺旋的呢?

我的思路是从子弹的出发点,到目标点连成一条直线,根据这条直线每帧绕这条直线往前动态旋转,就是我们的螺旋导弹了

我是用LAYA项目实现的 代码大概如下:

private currentAngle:number = 0;//当前绕AB点直线的角度

//当前直线位置,用于计算螺旋路径

private dirPos:Laya.Vector3 = new Laya.Vector3();

//子弹速度

private speedV3:Laya.Vector3 = new Laya.Vector3();

private Radius:number = 0;//绕AB点直线螺旋的半径,这个半径会在每帧动态改变,特别是从子弹发出时,到稳定螺旋,最后要到目的地时半径又缩小,这个自己实际测试时根据实际需求设定

//开始点到结束点的长度

private shootLength:number = 0;

onUpdate():void{

              

                Laya.Vector3.add( this.dirPos , speedV3 , this.dirPos );

                this.dirPos.cloneTo( this.pos );      

 

                this.target.transform.position = this.dirPos;//上一次路径值

                this.target.transform.translate( speedV3 , false )

                this.target.transform.position.cloneTo( this.dirPos );

 

                let shootLenth:number = this.shootLength;//开始点到结束点的距离

                let halfShootLength:number =  this.shootLenth * 0.4;

                let curLength:number = Laya.Vector3.distance( this.pos , this.to );//当前位置到结束点的直线距离

                

                //当前点右侧的一个点

                // this.cloneTransfom3D.getRight( this.right );

                this.target.transform.getRight( this.right );

                Laya.Vector3.normalize( this.right , this.right );

                

                Laya.Vector3.scale( this.right , this.Radius , this.right );//旋转半径

                Laya.Vector3.add( this.pos , this.right , this.pos );

                //旋转右侧点到对应角度

                this.pos = MathUtils.rotationPoint( this.pos , this.from , this.to , this.currentAngle );

               this.target.transform.position = this.pos;

                this.currentAngle += this.bullet6_angle;//每帧螺旋角度

                let perR = this.bullet6_radius * 0.2;

                if( curLength < halfShootLength ){//当前位置超过目标一半距离,则旋转半径开始缩小,达到精准目的

                    this.Radius -= perR;

                    if( this.Radius < 0 ) this.Radius = 0;

                }else if( this.Radius < this.bullet6_radius ){

                    this.Radius += perR ;//螺旋半径,从0开始涨到需要的值

                }else{

                    this.Radius = this.bullet6_radius ;//螺旋半径,从0开始涨到需要的值

                }

}

 

/**

     * 空间任意点沿着任意一条直线旋转的实现,制作螺旋导弹

     * https://blog.csdn.net/weixin_38168173/article/details/99931308

     * https://blog.csdn.net/dfdfdsfdfdfdf/article/details/53157491

     * @param point 要旋转的点

     * @param from  空间线段的起始点

     * @param to    空间线段的结束点

     * @param angle 旋转角度

     */

    public static rotationPoint(point: Laya.Vector3, from: Laya.Vector3, to: Laya.Vector3, angle: number): Laya.Vector3 {

 

        let x = point.x;

        let y = point.y;

        let z = point.z;

 

        let a = from.x;

        let b = from.y;

        let c = from.z;

 

        let l = this.angleToRadian(angle);

        let forward: Laya.Vector3 = this.getForward(from, to);

        let u = forward.x;

        let v = forward.y;

        let w = forward.z;

 

        let SinA = Math.sin(l);

        let CosA = Math.cos(l);

 

        let uu = u * u;

        let uv = u * v;

        let uw = u * w;

        let vv = v * v;

        let vw = v * w;

        let ww = w * w;

        let au = a * u;

        let av = a * v;

        let aw = a * w;

        let bu = b * u;

        let bv = b * v;

        let bw = b * w;

        let cu = c * u;

        let cv = c * v;

        let cw = c * w;

 

        let t00 = uu + (vv + ww) * CosA;

        let t01 = uv * (1 - CosA) + w * SinA;

        let t02 = uw * (1 - CosA) - v * SinA;

        let t03 = 0;

 

        let t10 = uv * (1 - CosA) - w * SinA;

        let t11 = vv + (uu + ww) * CosA;

        let t12 = vw * (1 - CosA) + u * SinA;

        let t13 = 0;

 

        let t20 = uw * (1 - CosA) + v * SinA;

        let t21 = vw * (1 - CosA) - u * SinA;

        let t22 = ww + (uu + vv) * CosA;

        let t23 = 0;

 

        let t30 = (a * (vv + ww) - u * (bv + cw)) * (1 - CosA) + (bw - cv) * SinA;

        let t31 = (b * (uu + ww) - v * (au + cw)) * (1 - CosA) + (cu - aw) * SinA;

        let t32 = (c * (uu + vv) - w * (au + bv)) * (1 - CosA) + (av - bu) * SinA;

        let t33 = 1;

 

        let pos: Laya.Vector3 = new Laya.Vector3();

        pos.x = t00 * x + t10 * y + t20 * z + t30;

        pos.y = t01 * x + t11 * y + t21 * z + t31;

        pos.z = t02 * x + t12 * y + t22 * z + t32;

        return pos;

    }

 

//这是点绕直线旋转的算法参考网站

 https://blog.csdn.net/weixin_38168173/article/details/99931308

 https://blog.csdn.net/dfdfdsfdfdfdf/article/details/53157491

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值