u2d弹射世界实现方案之数学方法计算弹射方向

 主要思路是计算获取弹板平面与圆形碰撞体的切点,切点与圆心相连获取正确的发射方向

通过下面的函数获取切点位置元组

public static (Vector2 point1,Vector2 point2) GetPointOfTangency(Vector2 pointOutOfCircle, Vector2 center, float radius)
    {
        Vector2 point1 = new Vector2(0, 0);
        Vector2 point2 = new Vector2(0, 0);
        var pointOfTangency = (point1:point1,point2:point2);
        //求出点到圆心的距离
        float distance = Mathf.Sqrt(Mathf.Pow(pointOutOfCircle.x - center.x, 2) + Mathf.Pow(pointOutOfCircle.y - center.y, 2));
        //判断是否符合要求 distance <= r 不符合则返回
        if(distance <= radius)
        {
            Debug.Log("error:数值不在范围内");
            return pointOfTangency;
        }

        //点p到切点的距离
        float length = Mathf.Sqrt(Mathf.Pow(distance, 2) - Mathf.Pow(radius, 2));
        //点到圆心的单位向量
        Vector2 pointToCenter = new Vector2(center.x - pointOutOfCircle.x, center.y - pointOutOfCircle.y).normalized;
        //test
        BoardRaycast.pointToCenter = pointToCenter;
        //计算切线与点心连线的夹角
        float angle = Mathf.Asin(radius / distance);

        //向正反两个方向旋转单位向量
        pointOfTangency.point1.x = pointToCenter.x * Mathf.Cos(angle) - pointToCenter.y * Mathf.Sin(angle);
        pointOfTangency.point1.y = pointToCenter.x * Mathf.Sin(angle) + pointToCenter.y * Mathf.Cos(angle);
        pointOfTangency.point2.x = pointToCenter.x * Mathf.Cos(-angle) - pointToCenter.y * Mathf.Sin(-angle);
        pointOfTangency.point2.y = pointToCenter.x * Mathf.Sin(-angle) + pointToCenter.y * Mathf.Cos(-angle);

        //test
        BoardRaycast.tanDir1 = pointOfTangency.point1;
        BoardRaycast.tanDir2 = pointOfTangency.point2;

        //得到新坐标
        pointOfTangency.point1.x = pointOfTangency.point1.x * length + pointOutOfCircle.x;
        pointOfTangency.point1.y = pointOfTangency.point1.y * length + pointOutOfCircle.y;
        pointOfTangency.point2.x = pointOfTangency.point2.x * length + pointOutOfCircle.x;
        pointOfTangency.point2.y = pointOfTangency.point2.y * length + pointOutOfCircle.y;
        return pointOfTangency;
    }
}

该方法参考自(9条消息) 求圆外一点做圆切线的切点坐标(算法)_计算圆外一点的切点_zdpBuilder的博客-CSDN博客但原文代码中的公式存在一些错误,笔者发布在此的函数是已修正后的版本。

public Vector2 GetFlipVector(Area area)
    {
        Vector2 flipDir = new Vector2();
        Vector2 center = ballCollider.transform.position;
        var pointOfTangency = Operator.GetPointOfTangency(raySourcePos,center,ballCollider.radius);
        if(area == Area.right)
        {
            flipDir = new Vector2(center.x - pointOfTangency.point1.x, center.y - pointOfTangency.point1.y).normalized;
        }
        else
        {
            flipDir = new Vector2(center.x - pointOfTangency.point2.x, center.y - pointOfTangency.point2.y).normalized;
        }
        //test();
        return flipDir;
    }

在获取了切点坐标后,更加弹珠所在屏幕位置选取正确的切点位置并与弹珠圆心做计算即可获取正确的弹射方向。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值