| 
									
										
										
										
											2022-09-04 11:35:13 +01:00
										 |  |  | using Godot; | 
					
						
							|  |  |  | using System; | 
					
						
							|  |  |  | using Vim.Math3d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public class Orbit | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-05 22:12:56 +01:00
										 |  |  |     // The position of the primary body relative to the ellipse - the  | 
					
						
							| 
									
										
										
										
											2022-09-04 11:35:13 +01:00
										 |  |  |     // orbit itself is presented as being centred on the primary, but | 
					
						
							| 
									
										
										
										
											2022-09-05 22:12:56 +01:00
										 |  |  |     // all our math is elliptical. | 
					
						
							| 
									
										
										
										
											2022-09-04 11:35:13 +01:00
										 |  |  |     private DVector2 PrimaryPosition => Ellipse.Focus0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public Ellipse Ellipse { get; set; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public DVector3 GetPosition(float t) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-09-05 22:12:56 +01:00
										 |  |  |         // TODO: determine period from mass of orbiting bodies | 
					
						
							|  |  |  |         var P = 10f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var a = Ellipse.a; | 
					
						
							|  |  |  |         var e = Ellipse.e; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var M = Kepler.GetMeanAnomaly(t, P); | 
					
						
							|  |  |  |         var E = Kepler.GetEccentricAnomaly(e, M) + Math.PI; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var p = Kepler.GetEccentricPosition2D(e, a, t); | 
					
						
							| 
									
										
										
										
											2022-09-04 11:35:13 +01:00
										 |  |  |         return new DVector3(p.X, 0, p.Y); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public void Draw(ImmediateGeometry geo) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         geo.Clear(); | 
					
						
							|  |  |  |         geo.Begin(Mesh.PrimitiveType.LineLoop); | 
					
						
							|  |  |  |         DrawEllipse(geo); | 
					
						
							|  |  |  |         geo.End(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private void DrawEllipse(ImmediateGeometry geo) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         geo.SetColor(new Color(1, 0, 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int steps = 100; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (int i = 0; i < steps; i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             float t = i / (float)steps; | 
					
						
							|  |  |  |             float a = t * Mathf.Tau; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var v2 = Ellipse.Focus0 + Ellipse.GetPosition(a); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             geo.AddVertex(new Godot.Vector3 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 x = (float)v2.X, | 
					
						
							|  |  |  |                 z = (float)v2.Y | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |