Astro  0.0.0
A C++ library for space dynamics
Loading...
Searching...
No Matches
Plotting.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * Copyright (c) 2025, Davide Stocco and Enrico Bertolazzi. *
3 * *
4 * The Astro project is distributed under the GNU GPLv3. *
5 * *
6 * Davide Stocco Enrico Bertolazzi *
7 * University of Trento University of Trento *
8 * e-mail: davide.stocco@unitn.it e-mail: enrico.bertolazzi@unitn.it *
9\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10
11#pragma once
12
13#ifdef ASTRO_ENABLE_PLOTTING
14
15#ifndef ASTRO_PLOTTING_HH
16#define ASTRO_PLOTTING_HH
17
18#include "Astro.hh"
19#include "Astro/Orbit.hh"
20
21// ROOT library
22#include <TApplication.h>
23#include <TCanvas.h>
24#include <TGraph.h>
25#include <TAxis3D.h>
26#include <TPolyLine3D.h>
27#include <TPolyMarker3D.h>
28#include <TGeoManager.h>
29#include <TGeoVolume.h>
30#include <TGeoSphere.h>
31#include <TGeoMatrix.h>
32#include <TMath.h>
33
34namespace Astro
35{
36 namespace Plotting
37 {
51 TObjArray* DrawAxes(Vector3 const & origin, Rotation const & rotation, Real const length = 1.0,
52 Real const line_width = 1.0)
53 {
54 TObjArray* arrows = new TObjArray();
55
56 // X-axis (Red)
57 TPolyLine3D* xAxis = new TPolyLine3D(2);
58 xAxis->SetPoint(0, origin.x(), origin.y(), origin.z());
59 Vector3 x_end(origin + rotation * Vector3(length, 0, 0));
60 xAxis->SetPoint(1, x_end.x(), x_end.y(), x_end.z());
61 xAxis->SetLineColor(kRed);
62 xAxis->SetLineWidth(line_width);
63 xAxis->Draw("same L");
64 arrows->Add(xAxis);
65
66 // Y-axis (Green)
67 TPolyLine3D* yAxis = new TPolyLine3D(2);
68 yAxis->SetPoint(0, origin.x(), origin.y(), origin.z());
69 Vector3 y_end(origin + rotation * Vector3(0, length, 0));
70 yAxis->SetPoint(1, y_end.x(), y_end.y(), y_end.z());
71 yAxis->SetLineColor(kGreen + 2);
72 yAxis->SetLineWidth(line_width);
73 yAxis->Draw("same L");
74 arrows->Add(yAxis);
75
76 // Z-axis (Blue)
77 TPolyLine3D* zAxis = new TPolyLine3D(2);
78 zAxis->SetPoint(0, origin.x(), origin.y(), origin.z());
79 Vector3 z_end(origin + rotation * Vector3(0, 0, length));
80 zAxis->SetPoint(1, z_end.x(), z_end.y(), z_end.z());
81 zAxis->SetLineColor(kBlue);
82 zAxis->SetLineWidth(line_width);
83 zAxis->Draw("same L");
84 arrows->Add(zAxis);
85
86 return arrows; // You can store/delete later
87 }
88
97 TObjArray* DrawAbsoluteAxes(Real const length = 1.0, Real const line_width = 1) {
98 return DrawAxes(ZEROS_VEC3, IDENTITY_MAT3, length, line_width);
99 }
100
110 TObjArray* DrawOrbitalPlaneAxes(Orbit const & orbit, Real length = 1.0, Real line_width = 1.0) {
111 // Get the orbital plane rotation matrix
112 Rotation rotation{orbit.keplerian_to_reference()};
113
114 // Draw the axes in the orbital plane
115 return DrawAxes(ZEROS_VEC3, rotation, length, line_width);
116 }
117
125 TPolyLine3D* DrawTrace(Eigen::Matrix<Real, 3, Eigen::Dynamic> const & trace) {
126 TPolyLine3D* poly_line = new TPolyLine3D(trace.cols());
127 for (int k = 0; k < trace.cols(); ++k) {
128 poly_line->SetPoint(k, trace(0, k), trace(1, k), trace(2, k));
129 }
130 poly_line->SetLineColor(kRed);
131 poly_line->SetLineWidth(2);
132 return poly_line;
133 }
134
142 TPolyLine3D* DrawTrace(Orbit const & orbit, Integer num_points = 360) {
143
144 // Extract orbital elements
145 Real a{orbit.keplerian().a};
146 Real e{orbit.keplerian().e};
147 Real i{orbit.keplerian().i};
148 Real Omega{orbit.keplerian().Omega};
149 Real omega{orbit.keplerian().omega};
150
151 // Precompute rotation values
152 Real cos_Omega{std::cos(Omega)};
153 Real sin_Omega{std::sin(Omega)};
154 Real cos_i{std::cos(i)};
155 Real sin_i{std::sin(i)};
156
157 TPolyLine3D* poly_line = new TPolyLine3D(num_points + 1);
158 for (int k = 0; k <= num_points; ++k) {
159 // Fictitious true anomaly in [0, 2pi]
160 Real nu{2.0 * TMath::Pi() * k / num_points};
161
162 // Radius from orbit equation
163 Real r{a*(1.0 - e*e)/(1.0 + e * std::cos(nu))};
164
165 // Rotate to inertial frame
166 Real cos_w_nu{std::cos(omega + nu)};
167 Real sin_w_nu{std::sin(omega + nu)};
168 Real x{r*(cos_Omega*cos_w_nu - sin_Omega*sin_w_nu*cos_i)};
169 Real y{r*(sin_Omega*cos_w_nu + cos_Omega*sin_w_nu*cos_i)};
170 Real z{r*(sin_w_nu*sin_i)};
171
172 poly_line->SetPoint(k, x, y, z);
173 }
174
175 poly_line->SetLineColor(kRed);
176 poly_line->SetLineWidth(2);
177 return poly_line;
178 }
179
189 //TObjArray* DrawFrenetSerretAxes(Orbit const & orbit, Real const length = 0.1, Real const line_width = 1.0) {
190 // return DrawAxes(orbit.cartesian().r, orbit.cartesian_to_frenet_rtn(), length, line_width); // FIXME cartesian_to_frenet_rtn()
191 //}
192
202 TPolyMarker3D* DrawMarker(Vector3 const & position, Color_t color, Real const size = 1.0) {
203 TPolyMarker3D* marker = new TPolyMarker3D(1);
204 marker->SetPoint(0, position.x(), position.y(), position.z());
205 marker->SetMarkerColor(color);
206 marker->SetMarkerSize(size);
207 marker->SetMarkerStyle(20); // Default marker style
208 marker->Draw("same P");
209 return marker;
210 }
211
221 TPolyMarker3D* DrawMarker(Body const & body, Color_t const color, Real const size = 1.0) {
222 return DrawMarker(body.orbit().cartesian().r, color, size);
223 }
224
235 TGeoVolume* DrawSphere(Vector3 const & position, Real const radius, Color_t const color, Real const line_width) {
236 static TGeoManager* geom = nullptr;
237
238 // Create TGeoManager only once
239 if (!geom) {
240 geom = new TGeoManager("SphereGeom", "Sphere Geometry");
241
242 // Material and medium
243 TGeoMaterial *mat = new TGeoMaterial("Vacuum", 0, 0, 0);
244 TGeoMedium *med = new TGeoMedium("VacuumMedium", 1, mat);
245
246 // Top volume large enough to contain everything
247 TGeoVolume *top = geom->MakeBox("TOP", med, 1000, 1000, 1000);
248 geom->SetTopVolume(top);
249 }
250
251 // Ensure the geometry is initialized
252 TGeoMedium* med = geom->GetMedium("VacuumMedium");
253 if (!med) {med = new TGeoMedium("VacuumMedium", 1, geom->GetMaterial("Vacuum"));}
254
255 // Create a unique sphere
256 static int sphere_id = 0;
257 std::string sphere_name = "Sphere_" + std::to_string(sphere_id++);
258 TGeoSphere* sphere = new TGeoSphere(0.0, radius);
259 TGeoVolume* volume = new TGeoVolume(sphere_name.c_str(), sphere, med);
260 volume->SetLineColor(color);
261 volume->SetLineWidth(line_width);
262
263 // Add to top volume
264 geom->GetTopVolume()->AddNode(volume, 1, new TGeoTranslation(position.x(), position.y(), position.z()));
265
266 // Draw top volume in wireframe
267 geom->CloseGeometry();
268 geom->GetTopVolume()->Draw("same");
269
270 return volume;
271 }
272
282 TGeoVolume* DrawSphere(Body const & body, Color_t const color, Real const line_width = 1.0) {
283 return DrawSphere(body.orbit().cartesian().r, body.radius(), color, line_width);
284 }
285
286
287 } // namespace Plotting
288
289} // namespace Astro
290
291#endif // ASTRO_PLOTTING_HH
292
293#endif // ASTRO_ENABLE_PLOTTING
The namespace for the Astro library.
Definition Astro.hh:73
Eigen::Matrix< Real, 3, 3 > Rotation
Definition Astro.hh:111
double Real
Definition Astro.hh:84
Eigen::Vector< Real, 3 > Vector3
Definition Astro.hh:93