# Question How much force do i need to apply in one frame in order for an object to stop at exact displacement?

Discussion in 'Physics' started by BlackRockShoota, May 23, 2023.

1. ### BlackRockShoota

Joined:
Apr 12, 2018
Posts:
4
Hi guys,

I am doing an experiment that I want to apply a force in one frame to a rigidbody using add force and I want it to be stop by friction at some displacement. I tried to calculate the force I need in the following code:
Code (CSharp):
1.         hitPosition = this.transform.position;
2.         isHitRecord = true;
3.         hitTime = DateTime.Now;
4.         var gravityDivide = Vector3.ProjectOnPlane(Physics.gravity, groundNormal) * ridbody.mass;
5.         var gravityFrictionDivide = Physics.gravity - gravityDivide;
6.         var frictionForceAcceleration =  bodyCollider.material.dynamicFriction * gravityFrictionDivide.magnitude;
7.
8.         var desiredV0 = (float)Math.Sqrt((2 * frictionForceAcceleration * distance));
9.         var acceleration = desiredV0 / Time.fixedDeltaTime;
10.
to calculate my desired v0 and apply the force with m * a, but the result is not quite what I want. What am I doing wrong? Any help appreciated

2. ### Maeslezo

Joined:
Jun 16, 2015
Posts:
278
Drag is a not a constant force, since it depends of the velocity.

However, you can approximate the behavior to an uniform accelerated motion if the displacement is small.

https://en.wikipedia.org/wiki/Acceleration#Uniform_acceleration

For instance, for displacement, the formula is speed = speed_initial^2 + 2*acceleration*displacement. Speed is 0, because you want to stop,
So drag (acceleration) = -speed_initial^2/(2*expected_displacement)

If you need an instant stop, you can generate an impulse opposite to the movement

Here's an example

Code (CSharp):
1. using UnityEngine;
2.
3. public class Stop : MonoBehaviour
4. {
5.     public Rigidbody rb;
6.
7.     public Vector3 dragAcc;
8.
9.     public bool doDrag;
10.     public float expectedTime = 1;
11.     public float expectedDisplacement = 5f;
12.
13.     public Vector3 positionStamp;
14.     public float timeStamp;
15.     void Start()
16.     {
17.
18.     }
19.
20.     // Update is called once per frame
21.     void Update()
22.     {
23.         if (Input.GetKeyDown(KeyCode.Space))
24.         {
25.             OneFrameStop();
26.         }
27.         if (Input.GetKeyDown(KeyCode.X))
28.         {
29.             //dragAcc = CalculateDragWithTime(rb.velocity, expectedTime);
30.             dragAcc = CalculateDragWithDisplacement(rb.velocity, expectedDisplacement);
31.             rb.useGravity = false;
32.             doDrag = true;
33.             positionStamp = transform.position;
34.             timeStamp = Time.time;
35.         }
36.     }
37.
38.     private void OneFrameStop()
39.     {
40.         Vector3 impulse = -rb.velocity; //just for testing
42.         rb.useGravity = false;
43.     }
44.
45.     private void FixedUpdate()
46.     {
47.         if (doDrag && rb.velocity.magnitude < 0.01f)
48.         {
49.             doDrag = false;
50.
51.             float displacement = (transform.position - positionStamp).magnitude;
52.             float time = Time.time - timeStamp;
53.
54.             print(\$"Time: Expected {expectedTime}. Actual {time}. Displacement: Expected {expectedDisplacement}. Actual {displacement}");
55.         }
56.
57.         if (doDrag)
58.         {
60.         }
61.     }
62.
63.     private static Vector3 CalculateDragWithTime(Vector3 velocity, float expectedTime)
64.     {
65.
66.         return -velocity / expectedTime;
67.     }
68.
69.     private static Vector3 CalculateDragWithDisplacement(Vector3 velocity, float expectedDisplacement)
70.     {
71.
72.         float speed = velocity.magnitude;
73.         return (-speed * speed) / (2f * expectedDisplacement) * velocity.normalized;
74.     }
75. }
76.