Jump to content

Parabolic arc (throwing a grenade)


Rick
 Share

Recommended Posts

  • 2 weeks later...

I have some code laying around from uhm.. a different engine when we were in class and practising this topic. Fortunately I still have the code:

 

Vector3 mvGravity;
Vector3 mvInitialVelocity;
Vector3 mvVelocity;
Vector3 mvInitialPosition;
Vector3 mvPosition;
float mfBounciness = 1.0f;
float mfTimeAtImpact = 0;
GameObject mgPivot;
// Use this for initialization
void Start () {
 mvVelocity = mvInitialVelocity;
 mvInitialPosition = mvPosition = transform.position;
 CalculateLandingPosition();
 DisplayTrailPath();
}
void CalculateLandingPosition()
{
 mgPivot.transform.position = CalculatePositionAtTime(CalculateLandingTime());
}
void DisplayTrailPath()
{
 float landingTime = CalculateLandingTime();
 for (float i = 0.0f; i < landingTime; i += Time.fixedDeltaTime) // You use fixed deltatime when it comes to physics
 {
  Debug.DrawRay(CalculatePositionAtTime(i), Vector3.up, Color.black, 5);
 }
}
float CalculateLandingTime()
{
 // Calculate per second per second
 return ABCFormula(.5f * mvGravity.y, mvInitialVelocity.y, mvInitialPosition.y)[1];
}
Vector3 CalculatePositionAtTime(float afTime)
{
 return .5f * mvGravity * afTime * afTime + mvInitialVelocity * afTime + mvInitialPosition;
}
Vector3 CalculateVelocityAtTime(float afTime)
{
 return mvGravity * afTime + mvInitialVelocity;
}
float[] ABCFormula(float A, float B, float C)
{
 float det = B * B - 4 * A * C;
 if (det < 0) return null;
 float DetSqrt = Mathf.Sqrt(det);
 return new float[] {
  (-B + DetSqrt) / (2*A),
  (-B - DetSqrt) / (2*A)
 };
}

// Update is called once per frame
void FixedUpdate () {
 // Move ball
 mvVelocity += mvGravity * Time.fixedDeltaTime;
 mvPosition += mvVelocity * Time.fixedDeltaTime;
 transform.position = mvPosition;
 Debug.DrawRay(transform.position, Vector3.up, Color.blue, CalculateLandingTime());
 // Bounce
 float fYPos = transform.localPosition.y;
 float fRadius = .5f;
 if (fYPos - fRadius <= 0)
 {
  mvVelocity.y *= -mfBounciness;
  if (mfTimeAtImpact == 0)
  {
   mfTimeAtImpact = Time.time;
   Debug.Log(Time.time + " seconds");
  }
 }
}

 

Which simulated this

Using Leadwerks Professional Edition (Beta), mainly using C++.

Windows 10 / Linux Mint, Visual Studio 2017. GPU: NVidia GeForce GTX970, CPU: Intel i7 7700K @ 4.20 GHz

Previously known as Evayr.

Link to comment
Share on other sites

So you're doing velocities and such. My idea was that I know my start and end points in which I would then calc the mid point and from those 3 points make a parabolic curve and then get the points along that curve and move over them smoothly.

 

vs sending an object in a direction and calculating that curve as it goes.

Link to comment
Share on other sites

Hmm in that case, you can take the average position of two points (like start and center) and set the height to 75% of the highest value. Then you can repeat this process for other points untill you have a clear curve.

 

Roughly sketched, you'd get something like this

post-358-0-08441800-1446603688.png

 

Or are you in need of a perfect curve? You could use this method an X amount of times till it looks smooth enough

Using Leadwerks Professional Edition (Beta), mainly using C++.

Windows 10 / Linux Mint, Visual Studio 2017. GPU: NVidia GeForce GTX970, CPU: Intel i7 7700K @ 4.20 GHz

Previously known as Evayr.

Link to comment
Share on other sites

If you got 3 points, just use a spline.

 

Example :

 

function smooth( points, steps )
   if #points < 3 then
       return points
   end

   local steps = steps or 500

   local spline = {}
   local count = #points - 1
   local p0, p1, p2, p3, x, y, h

   for i = 1, count do

       if i == 1 then
           p0, p1, p2, p3 = points[i], points[i], points[i + 1], points[i + 2]
       elseif i == count then
           p0, p1, p2, p3 = points[#points - 2], points[#points - 1], points[#points], points[#points]
       else
           p0, p1, p2, p3 = points[i - 1], points[i], points[i + 1], points[i + 2]
       end    

       for t = 0, 1, 1 / steps do
           x = 0.5 * ( ( 2 * p1.x ) + ( p2.x - p0.x ) * t + ( 2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x ) * t * t + ( 3 * p1.x - p0.x - 3 * p2.x + p3.x ) * t * t * t )
           y = 0.5 * ( ( 2 * p1.y ) + ( p2.y - p0.y ) * t + ( 2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y ) * t * t + ( 3 * p1.y - p0.y - 3 * p2.y + p3.y ) * t * t * t )
           h = 0.5 * ( ( 2 * p1.h ) + ( p2.h - p0.h ) * t + ( 2 * p0.h - 5 * p1.h + 4 * p2.h - p3.h ) * t * t + ( 3 * p1.h - p0.h - 3 * p2.h + p3.h ) * t * t * t )

           --prevent duplicate entries
           if not(#spline > 0 and spline[#spline].x == x and spline[#spline].y == y) then
               table.insert( spline , { x = x , y = y, h = h } )                
           end    
       end

   end    
   return spline
end

 

Visual example, by drawing 20 boxes aling the spline of 3 points

 

   points = { }
   table.insert( points, { x=-5,y=28, h=17 })  -- start
   table.insert( points, { x=-5,y=38, h=39 })  -- top
   table.insert( points, { x=-5,y=48, h=17 })  -- end

   --make spline of points, 20 iterations
   local arc=smooth( points,20)

   --visualize arc
   for k,v in pairs( arc )
   do
       Model:Box():SetPosition(v.x,v.h,v.y)
   end

  • Upvote 4

HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB

Link to comment
Share on other sites

Thanks Shadmar! You know I just found that code this morning on github but I asked the guy if he could make it 3D as it was 2D. I assume your 'h' is 'z'? Why the 'h' instead of 'z'? Just curious.

It might be left handed.

 

This code is awesome. This is what I need to create a faith plate. Thanks.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...