Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by CupOfMayo · Oct 09, 2014 at 09:19 AM · physicsmathprojectileorbit

Calculating trajectory of elliptical orbit?

Hey, yesterday I did a basic script what draws trajectory of an Object in future. Here's a part what actually calculate all that. (I already asked simillar question but there was no answer at all and now I actually understand what I need).

 for(i = 0; i < 30; i++)
     {
         
         x = rigidbody.velocity.x * i;
         z = rigidbody.velocity.z * i;
         y = rigidbody.velocity.y * i + (Physics.gravity.y)/2 * Mathf.Pow(i, 2);
         var pos = Vector3(x,y,z);
         lineRenderer.SetPosition(i,transform.position + pos);

             //y = yvo * t * g/2 * i^2;
         
     }

And It look like this(look at attachment with red trajectory)

Now I want to modify it so it will draw orbit of satellite what orbits planet so It will look somewhat like this(look at attachment with planet and satellite)

Here's a script what I use to simulate Gravity (attached to object with rigidbody what doesn't use gravity).

 var other : GameObject;  //planet   
 var gravity : float = 10;
 var dist : float;     
 var distSqr : float;
 var force : float;
 var dir : Vector3;
          
 function FixedUpdate()
 {
     AddGravity();
 }
      
 function AddGravity()
 {
     dir = (other.transform.position - transform.position); //force direction
     dist = Vector3.Distance(other.transform.position, transform.position); //calculate distance between object and planet
     distSqr = dist * dist; //distance^2
     force = gravity / distSqr; //calculate force
     rigidbody.AddForce(dir.normalized * force, ForceMode.Acceleration); //add force
     
     
     
 }


If you have any idea how can I achieve that please let me know :).

7391a47b8aa777cd52c5c93905b82367.png (6.4 kB)
d5f335d30e1c7336f02b0e993c55dde5.png (7.1 kB)
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Scribe · Oct 09, 2014 at 09:45 AM 0
Share

A few things I can think of, I'm guessing your second script just results in your object falling toward the orbit centre? This is probably because you have no motion perpendicular to the dir of gravity to cause an orbit, You can find the maths to calculate this by searching for $$anonymous$$epler's second law of planetary motion, alternatively and probably easier, if you make sure that your rigidbody has no drag forces, you could simply give the planet an initial perpedicular force or push, and the physics engine ~should~ produce an orbit (given the initial value is within some range based on distance and mass of you central object).

The other little thing you should change is calculating your distSqr value, calculating distance and then squaring is not very efficient as finding the distance uses an algorithm that squareroots a number which is not a very efficient algorithm. doing distSqr = dir.sqr$$anonymous$$agnitude; would be far more efficient!

avatar image CupOfMayo · Oct 09, 2014 at 09:55 AM 0
Share

Yeah that script may not be the most efficient but that's not the problem. Satellite is orbiting the planet the way it should(just adding a push with another script in function Start() ). $$anonymous$$y problem is how do I calculate where the satellite will be in next sec, 2sec and so on; so I can predict the whole orbit.

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Scribe · Oct 09, 2014 at 09:50 PM

Hi again, sorry for the delay!

So when writing that comment I hadn't understood the question, my suggestion would be to basically run a fast simulation of what your satellite would do and track the positions it hits. The way I do this is by defining a point and then running a loop which saves the point, the recalculates it's position as it would appear one physics time step later, saves that position and so on. This appears to work nicely apart unless you have your object going very close to the planet with very high gravity, at which point there are so errors caused by the fact that large amounts of distance are covered in the small time step, but I expect these errors might occur with your actual object too. If you need to fix that, try reducing the dt variable!

 var other : GameObject;
 var gravity : float = 100;
 var startingVelocity : Vector3 = Vector3.up;
 private var distSqr : float;     
 private var force : float;
 private var dir : Vector3;
 private var orbitPoints : Vector3[];
 var maxCount : int = 10000;
 var simplify : int = 5;
 private var privateMaxCount : int;
 var lineRenderer : LineRenderer;
 
 function Start () {
     privateMaxCount = maxCount;
     orbitPoints = new Vector3[privateMaxCount];
     lineRenderer = gameObject.AddComponent(LineRenderer);
     lineRenderer.SetWidth(0.2,0.2);
     ComputeTrajectory();
 }
 
 function ComputeTrajectory () {
     dir = (other.transform.position - transform.position);
     var angle : float = 0;
     var dt : float = Time.fixedDeltaTime;
     var s : Vector3 = transform.position - other.transform.position;
     var lastS : Vector3 = s;
     var v : Vector3 = startingVelocity;
     var a : Vector3 = dir.normalized*gravity/dir.sqrMagnitude;
     var d : Vector3 = dir;
     var tempAngleSum : float = 0;
     var step : int = 0;
     while(angle < 360 && step < privateMaxCount*simplify){
         if(step % simplify == 0){
             orbitPoints[step/simplify] = s+other.transform.position;
             angle += tempAngleSum;
             tempAngleSum = 0;
         }
         d = -s;
         a = d.normalized*gravity/d.sqrMagnitude;
         v += a*dt;
         s += v*dt;
         tempAngleSum += Mathf.Abs(Vector3.Angle(s, lastS));
         lastS = s;
         step ++;
     }
     lineRenderer.SetVertexCount(step/simplify);
     for(var i : int = 0; i < step/simplify; i++){
         lineRenderer.SetPosition(i, orbitPoints[i]);
     }
 }


Hopefully your satellites are (mostly) on fixed orbit paths as this code is quite inefficient and should be called as little as possible!

Hope that helps,

Scribe

EDIT:

 var gravityObjects : GravityObject[];
 var startingVelocity : Vector3 = Vector3.up;
 private var dir : Vector3;
 private var orbitPoints : Vector3[];
 var maxCount : int = 10000;
 var simplify : int = 5;
 private var privateMaxCount : int;
 private var lineRenderer : LineRenderer;
 
 function Start () {
     privateMaxCount = maxCount;
     orbitPoints = new Vector3[privateMaxCount];
     lineRenderer = gameObject.AddComponent(LineRenderer);
     lineRenderer.SetWidth(0.2,0.2);
     ComputeTrajectory();
 }
 
 function Update(){
     if(Input.GetKeyDown(KeyCode.W)){
         ComputeTrajectory();
     }
 }
 
 function ComputeTrajectory () {
     var angle : float = 0;
     var dt : float = Time.fixedDeltaTime;
     var s : Vector3 = transform.position;
     var lastS : Vector3 = s;
     
     var v : Vector3 = startingVelocity;
     var a : Vector3 = AccelerationCalc(gravityObjects, s);
     var tempAngleSum : float = 0;
     var step : int = 0;
     while(angle < 360 && step < privateMaxCount*simplify){
         if(step % simplify == 0){
             orbitPoints[step/simplify] = s;
             angle += tempAngleSum;
             tempAngleSum = 0;
         }
         a = AccelerationCalc(gravityObjects, s);
         v += a*dt;
         s += v*dt;
         if(gravityObjects.Length == 1){
             tempAngleSum += Mathf.Abs(Vector3.Angle(s, lastS));
         }
         lastS = s;
         step ++;
     }
     lineRenderer.SetVertexCount(step/simplify);
     for(var i : int = 0; i < step/simplify; i++){
         lineRenderer.SetPosition(i, orbitPoints[i]);
     }
 }
 
 function AccelerationCalc(goArray : GravityObject[], simPos : Vector3){
     var a : Vector3 = Vector3.zero;
     for(var i : int = 0; i < goArray.Length; i++){
         dir = goArray[i].trans.position - simPos;
         gravity = goArray[i].g;
         a += dir.normalized*gravity/dir.sqrMagnitude;
     }
     return a;
 }
 
 class GravityObject{
     var trans : Transform;
     var g : float;
     
     function GravityObject(some_Transform : Transform, grav : float){
         trans = some_Transform;
         g = grav;
     }
 }

so here I have set up a new class called GravityObject which just saves the transform and gravity strength of an instance, then I have a new variable which is a list of these GravityObjects and then the acceleration of your satellite is calculated based on each element in the list!

Comment
Add comment · Show 10 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CupOfMayo · Oct 10, 2014 at 09:15 AM 0
Share

Wow I don't know how you did it, but it works :) Actually it works even better than i expected, now I have to understand what you did there a little better so I'll know exactly how it works :) Thank you! Btw. I'll actually have to edit it a little more on my own so i can use it as Update but at least I have great reference to base on.

avatar image Scribe · Oct 10, 2014 at 05:04 PM 0
Share

To make it better for running from Update, you could increase the dt variable, increase 'simplify' (for large orbits you can make this very large ~100) and merging the second for loop where I actually set the linrenderer positions into the while loop would help a lot as well! If you have any questions about what I've done or having trouble understanding stuff, feel free to ask :)

avatar image CupOfMayo · Oct 10, 2014 at 08:13 PM 0
Share

Yeah I noticed that. Btw do you think theres a way to draw orbit while theres more than one soruce of gravity? Like let's say there are 2 planets close to each other and they are influenting satallite?

avatar image Scribe · Oct 11, 2014 at 02:57 PM 0
Share

You definitely can, though making that efficient enough to work from Update will be quite a challenge, unless you plan to have nothing else in your scene! The other problem is that unless you have some very nice starting conditions, 3 body gravity movements are very erratic and strange, normally ending with your object flying off at infinite speed into space! But check my edit anyway, it should help :)

avatar image CupOfMayo · Oct 11, 2014 at 08:09 PM 0
Share

Haha this is perfect! :) alt text

You are genius my friend, now ill just have to figure it out so it will also work with moving objects :P And I guess that's not a big deal. But seriously, are you physicist or something? I could never fighure that out on my own; Thanks again.

Show more comments
avatar image
0

Answer by sorcerer_supreme · Feb 07, 2017 at 01:42 PM

@Scribe Thanks a lot. This post is like 2 years old now. I implemented this trajectory function just like you did, i just kept acceleration constant so that I didn't have to compute it every frame. But the main problem I faced was too many calculations per frame. It never struck me that its not necessary to calculate it in a single frame. This countperFrame trick works like a charm. You are awesome..!!!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

30 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Trying to move an object towards another's axis. 1 Answer

Calculate Height of Trajectory : Unity3d 1 Answer

Finding the axis of a curving pipe 0 Answers

shoot a cannon ball cannot run !! 0 Answers

The name 'Joystick' does not denote a valid type ('not found') 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges