Throwing ball on PowerApps

In many games, it is very important to naturally realise physical phenomena such as jumps, collisions, reflections, and bounds.
My previous post, it has been shown that the motion of projectile with air resistance and gravity can be realized on PowerApps.

In this post, I would explain how we can treat bounce and reflection events on PowerApps.
In addition to the implementation on PowerApps, will refer to a basic approach for these events with some mathematical expressions.
#Physics
###Throwing ball 
First, the motion of throwing ball is described by Equation of motion for Projectile with gravity and air resistance.
<img width="841" alt="motionofball.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/202779/96233677-3b9c-1291-54d6-ade482eb192f.png">
It is very important to estimate velocity *u(t)* and *v(t)* in order to realise bounce and reflection.
Next, we consider the event of bounce and reflection, it is not much difficult.

###Bounce
Both before & after the bounce, the motion of ball is given by EoM of projectile.
The only difference is its velocity.  
As you can find from following figure, **vertical component of velocity is flipped** after the bounce, and (may) bit decreased which is expressed by ε*.
  * ε : coefficient of restitution. 
Value of ε is determined by material of floor/wall.  If floor is made by metal, ε is almost 1 (no velocity loss), but if floor is dirt, ε becomes much smaller than 1.
 
<img width="847" alt="bounce.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/202779/d01e1f49-fbe7-202f-8f3c-71ca7c5341ea.png">
So, the motion of ball after bounce is projectile motion with initial velocity *ua* and *va*

###Reflection
As is the case in bounce, the effect of reflection is simply realised by following relation. In contrast to the case of bounce, horizontal component of velocity becomes opposite to one before reflection.
<img width="709" alt="reflection.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/202779/9440ff30-ba33-458c-6b1f-004d867da29b.png">

#PowerApps

Now, you can implement these motion and effects into PowerApps!
Fine things aside, my app is constructed by 3 objects (ball, wall, and floor)+ 1 timer control.
<img height="200" src="https://qiita-image-store.s3.amazonaws.com/0/202779/ff1fb840-af32-1d4e-e451-424f85e00e44.png">

X and Y Properties of ball object are as;

```Ball.X
X0+ (vx0/AirResist.Text)* (1-Exp(-1*AirResist.Text * T))
```
```Ball.Y
Y0-(vy0/AirResist.Text)*(1+GravityConst.Text/(AirResist.Text*vy0)) * (1-Exp(-1*AirResist.Text * T)) + GravityConst.Text * T/AirResist.Text
```
where *X0, Y0* are initial position of ball, and *vx0 , vy0* are initial velocity.

In order to move ball object, context variable T (time) is updated on every timer end;

```Timer.OnTimerEnd
T: T + Timer.Duration/1000
```
Typically Timer.Duration is 50~100 millisecond. The ball now moves, but not sufficient.
We have to implement the effect of bounce and reflection. The whole block of code for OnTimerEnd is given by;

```Timer.OnTimerEnd
If(
    //[Reflection] 
    //1. Flip sign of velocity X and set as initial velocity vx0
    //2. Initialize time T (Recast @next OnTimerEnd)
    Xnow > MainScreen.Width-Wall.Width-Ball.Width,
    UpdateContext(
        {
            T:0,
            vx0: -1.0*vxnow* (100-VelocityLoss.Text)/100,
            vy0: vynow,
            X0: Ball.X,
            Y0: Ball.Y,
            Xnow: Ball.X
        }
    ),
    If(
        //[Bounce] 
        //1. Flip sign of velocity Y and set as initial velocity vy0
        //2. Initialize time T (Recast @next OnTimerEnd)
        Ynow > MainScreen.Height-Floor.Height-Ball.Height,
        UpdateContext(
            {
                T: 0,
                X0: Ball.X,
                Y0: Ball.Y,
                vx0: vxnow,
                vy0: -1.0*vynow * (100-VelocityLoss.Text)/100,
                Ynow: Ball.Y
            }
        ),
        UpdateContext(
            {
                vxnow: vx0 * Exp(-1 * AirResist.Text * (T+Timer.Duration/1000)),
                vynow: vy0 * (1 + GravityConst.Text/(AirResist.Text * vy0)) * (Exp(-1 * AirResist.Text * (T + Timer.Duration/1000))) - GravityConst.Text/AirResist.Text,
                //Xnow,Ynow show the position of Ball at the next step
                Xnow: X0 + (vx0/AirResist.Text) * (1-Exp(-1 * AirResist.Text * (T + 2*Timer.Duration/1000))),
                Ynow: Y0-(vy0/AirResist.Text) * (1 + GravityConst.Text/(AirResist.Text * vy0)) * (1-Exp(-1 * AirResist.Text * (T + 2*Timer.Duration/1000))) + GravityConst.Text * (T + 2*Timer.Duration/1000)/AirResist.Text,
                T: T + Timer.Duration/1000
            }
        )
    )
)
```
First part of above, ```Xnow > MainScreen.Width-Wall.Width-Ball.Width```, determine whether the ball collides with wall or not. It true, set current velocity/position into initial velocity/position for next projectile.
Also, second part, ```Ynow > MainScreen.Height-Floor.Height-Ball.Height```, determine the condition of bounce event. If true, as in the case of reflection, set current velocity/position into initial velocity/position for next projectile.

That's all physics and implementation of My App!
You can download this app from [PowerApps Community Gallery](https://powerusers.microsoft.com/t5/Community-Apps-Gallery/Throwing-a-Ball/m-p/180730) !