Пример #1
0
        public BankStepInfo ComputeStep(IBallInternal ball)
        {
            BankStepInfo res = new BankStepInfo(double.PositiveInfinity, Coordinates.Zero, Coordinates.Zero);

            foreach (var bank in c_Banks)
            {
                var tmp = ComponentManager.Cache.Get(bank, ball.Position, ball.Velocity, ball.Friction);
                if (tmp != null)
                {
                    res = new BankStepInfo(tmp.Step, tmp.Normal, tmp.Tangent);
                }
                else
                {
                    UpdateStep(ref res, bank, ball);
                    ComponentManager.Cache.Add(res.Step, res.NormalVersor, res.TangentVersor, bank, ball.Position, ball.Velocity, ball.Friction);
                }
            }
            foreach (var corner in c_BankCorners.Where((c, i) => IsCornerValidForCollision(i)))
            {
                var tmp = ComponentManager.Cache.Get(corner, ball.Position, ball.Velocity, ball.Friction);
                if (tmp != null)
                {
                    res = new BankStepInfo(tmp.Step, tmp.Normal, tmp.Tangent);
                }
                else
                {
                    UpdateStep(ref res, corner, ball);
                    ComponentManager.Cache.Add(res.Step, res.NormalVersor, res.TangentVersor, corner, ball.Position, ball.Velocity, ball.Friction);
                }
            }
            return(res);
        }
Пример #2
0
 private void SetVelocity(Coordinates newVelocity, bool calcStep)
 {
     if (newVelocity.Module < m_PhysicsData.FrictionCoefficient)
     {
         m_Velocity = Coordinates.Zero;
     }
     else
     {
         m_DirectionUpdated = !(m_Velocity.Phase % 360.0).ToleranceEqual(newVelocity.Phase % 360.0);
         m_Velocity         = newVelocity;
     }
     if (calcStep && m_Velocity.Module > 0)
     {
         m_BankStep = m_Table.ComputeStep(this);
     }
 }
Пример #3
0
        private void UpdateStep(ref BankStepInfo info, ICoordinates corner, IBallInternal ball)
        {
            double distance = double.PositiveInfinity;
            int    N        = -1;

            while (distance > ball.Radius)
            {
                N++;
                double newDistance = GeometryUtils.Distance(ball.ForeseenPosition(N), corner);
                if (newDistance >= distance)
                {
                    return;
                }
                else
                {
                    distance = newDistance;
                }
            }
            N--;
            var    p            = ball.ForeseenPosition(N);
            var    v            = ball.ForeseenVelocity(N);
            double a            = v.X * (corner.X - p.X) + v.Y * (corner.Y - p.Y);
            double c            = Math.Pow(v.X, 2) + Math.Pow(v.Y, 2);
            double b            = Math.Sqrt(Math.Pow(a, 2) - c * (Math.Pow(corner.X - p.X, 2) + Math.Pow(corner.Y - p.Y, 2) - Math.Pow(ball.Radius, 2)));
            double t1           = (a + b) / c;
            double t2           = (a - b) / c;
            double t            = (t1.Between(0, 1) ? (t2.Between(0, 1) ? Math.Min(t1, t2) : t1) : (t2.Between(0, 1) ? t2 : double.PositiveInfinity));
            var    ballCenter   = Coordinates.Add(p, t * v);
            var    contactPoint = Coordinates.Add(ballCenter, Coordinates.Sub(corner, ballCenter));

            if (!CheckCenterPoint(ballCenter, ball.Radius) || !CheckContactPoint(contactPoint))
            {
                return;
            }
            double step = N + t;

            if (!step.ToleranceEqual(0) && step.ToleranceLessEqual(info.Step))
            {
                if (step < info.Step)
                {
                    var normal  = Coordinates.Normalize(Coordinates.Sub(p, corner));
                    var tangent = new Coordinates(module: 1, phase: normal.Phase + 90);
                    info = new BankStepInfo(step, normal, tangent);
                }
            }
        }
Пример #4
0
        private void UpdateStep(ref BankStepInfo info, Line2 bank, IBallInternal ball)
        {
            double distance = double.PositiveInfinity;
            int    N        = -1;

            while (distance > ball.Radius)
            {
                N++;
                double newDistance = GeometryUtils.Distance(ball.ForeseenPosition(N), bank);
                if (newDistance >= distance)
                {
                    return;
                }
                else
                {
                    distance = newDistance;
                }
            }
            N--;
            var    p            = ball.ForeseenPosition(N);
            var    v            = ball.ForeseenVelocity(N);
            double a            = bank.A * p.X + bank.B * p.Y + bank.C;
            double b            = ball.Radius * Math.Sqrt(Math.Pow(bank.A, 2) + Math.Pow(bank.B, 2));
            double c            = bank.A * v.X + bank.B * v.Y;
            double t1           = (-a + b) / c;
            double t2           = (-a - b) / c;
            double t            = (t1.Between(0, 1) ? (t2.Between(0, 1) ? Math.Min(t1, t2) : t1) : (t2.Between(0, 1) ? t2 : double.PositiveInfinity));
            var    ballCenter   = Coordinates.Add(p, t * v);
            var    contactPoint = Coordinates.Add(ballCenter, -ball.Radius * bank.NormalVersor);

            if (!CheckCenterPoint(ballCenter, ball.Radius) || !CheckContactPoint(contactPoint))
            {
                return;
            }
            double step = N + t;

            if (!step.ToleranceEqual(0) && step.ToleranceLessEqual(info.Step))
            {
                if (step < info.Step)
                {
                    info = new BankStepInfo(step, bank.NormalVersor, bank.Versor);
                }
            }
        }