Skip to content

Commit 8658ad1

Browse files
authored
Merge pull request #4213 from pleroy/ANewHope
PlotMethod4: A New Hope
2 parents a4f09e7 + 406cb69 commit 8658ad1

14 files changed

+435
-64
lines changed

Principia.sln.DotSettings

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
<s:Boolean x:Key="/Default/UserDictionary/Words/=colour/@EntryIndexedValue">True</s:Boolean>
222222
<s:Boolean x:Key="/Default/UserDictionary/Words/=colours/@EntryIndexedValue">True</s:Boolean>
223223
<s:Boolean x:Key="/Default/UserDictionary/Words/=downsampling/@EntryIndexedValue">True</s:Boolean>
224+
<s:Boolean x:Key="/Default/UserDictionary/Words/=equipotential/@EntryIndexedValue">True</s:Boolean>
224225
<s:Boolean x:Key="/Default/UserDictionary/Words/=Frenet/@EntryIndexedValue">True</s:Boolean>
225226
<s:Boolean x:Key="/Default/UserDictionary/Words/=geopotential/@EntryIndexedValue">True</s:Boolean>
226227
<s:Boolean x:Key="/Default/UserDictionary/Words/=gipfeli/@EntryIndexedValue">True</s:Boolean>

benchmarks/planetarium_benchmark.cpp

+61-1
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,13 @@ class Satellites {
220220
}
221221

222222
Planetarium MakePlanetarium(
223+
Angle const& angular_resolution,
223224
Perspective<Navigation, Camera> const& perspective,
224225
not_null<PlottingFrame const*> plotting_frame) const {
225226
// No dark area, human visual acuity, wide field of view.
226227
Planetarium::Parameters parameters(
227228
/*sphere_radius_multiplier=*/1,
228-
/*angular_resolution=*/0.4 * ArcMinute,
229+
angular_resolution,
229230
/*field_of_view=*/90 * Degree);
230231
Instant const t = goes_8_trajectory().front().time;
231232
Similarity<Navigation, GCRS> const plotting_to_gcrs =
@@ -316,6 +317,7 @@ void BM_PlanetariumPlotMethod3(
316317
Instant const t = satellites.goes_8_trajectory().front().time;
317318
PlottingFrame const& plotting = (satellites.*plotting_frame)();
318319
Planetarium planetarium = satellites.MakePlanetarium(
320+
0.4 * ArcMinute,
319321
perspective((satellites.gcrs().ToThisFrameAtTimeSimilarly(t) *
320322
plotting.FromThisFrameAtTimeSimilarly(t)).similarity(),
321323
distance_from_earth),
@@ -350,6 +352,52 @@ void BM_PlanetariumPlotMethod3(
350352
.str());
351353
}
352354

355+
void BM_PlanetariumPlotMethod4(
356+
benchmark::State& state,
357+
Perspective<Navigation, Camera> (*const perspective)(
358+
Similarity<Navigation, GCRS> const& navigation_to_gcrs_at_epoch,
359+
Length const distance_from_earth),
360+
Length const distance_from_earth,
361+
PlottingFrame const& (Satellites::*const plotting_frame)() const) {
362+
static Satellites satellites;
363+
Instant const t = satellites.goes_8_trajectory().front().time;
364+
PlottingFrame const& plotting = (satellites.*plotting_frame)();
365+
Planetarium planetarium = satellites.MakePlanetarium(
366+
1 * ArcMinute,
367+
perspective((satellites.gcrs().ToThisFrameAtTimeSimilarly(t) *
368+
plotting.FromThisFrameAtTimeSimilarly(t)).similarity(),
369+
distance_from_earth),
370+
&plotting);
371+
std::vector<ScaledSpacePoint> line;
372+
int iterations = 0;
373+
// This is the time of a lunar eclipse in January 2000.
374+
constexpr Instant now = "2000-01-21T04:41:30,5"_TT;
375+
for (auto _ : state) {
376+
line.clear();
377+
planetarium.PlotMethod4(
378+
satellites.goes_8_trajectory(),
379+
satellites.goes_8_trajectory().begin(),
380+
satellites.goes_8_trajectory().end(),
381+
/*t_max=*/InfiniteFuture,
382+
/*reverse=*/false,
383+
/*add_point=*/
384+
[&line](ScaledSpacePoint const& point) { line.push_back(point); },
385+
/*max_points=*/std::numeric_limits<int>::max());
386+
++iterations;
387+
}
388+
Interval<double> x;
389+
Interval<double> y;
390+
Interval<double> z;
391+
for (auto const& point : line) {
392+
x.Include(point.x);
393+
y.Include(point.y);
394+
z.Include(point.z);
395+
}
396+
state.SetLabel((std::stringstream() << line.size() << " points within " << x
397+
<< " × " << y << " × " << z)
398+
.str());
399+
}
400+
353401
#define PRINCIPIA_BENCHMARK_PLANETARIUM_PLOT_METHODS_NEAR_AND_FAR( \
354402
name, perspective, plotting_frame) \
355403
BENCHMARK_CAPTURE(BM_PlanetariumPlotMethod3, \
@@ -358,11 +406,23 @@ void BM_PlanetariumPlotMethod3(
358406
near, \
359407
(plotting_frame)) \
360408
->Unit(benchmark::kMillisecond); \
409+
BENCHMARK_CAPTURE(BM_PlanetariumPlotMethod4, \
410+
Near##name, \
411+
(perspective), \
412+
near, \
413+
(plotting_frame)) \
414+
->Unit(benchmark::kMillisecond); \
361415
BENCHMARK_CAPTURE(BM_PlanetariumPlotMethod3, \
362416
Far##name, \
363417
(perspective), \
364418
far, \
365419
(plotting_frame)) \
420+
->Unit(benchmark::kMillisecond); \
421+
BENCHMARK_CAPTURE(BM_PlanetariumPlotMethod4, \
422+
Far##name, \
423+
(perspective), \
424+
far, \
425+
(plotting_frame)) \
366426
->Unit(benchmark::kMillisecond)
367427

368428
#define PRINCIPIA_BENCHMARK_PLANETARIUM_PLOT_METHODS_POLAR_AND_EQUATORIAL( \

geometry/perspective.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Perspective final {
4343
Perspective(Similarity<FromFrame, ToFrame> const& to_camera,
4444
Length const& focal);
4545

46+
Position<FromFrame> const& camera() const;
4647
Length const& focal() const;
4748

4849
// Returns the ℝP² element resulting from the projection of `point`. This

geometry/perspective_body.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ Perspective<FromFrame, ToFrame>::Perspective(
4242
camera_(from_camera_(ToFrame::origin)),
4343
focal_(focal) {}
4444

45+
template<typename FromFrame, typename ToFrame>
46+
Position<FromFrame> const&
47+
Perspective<FromFrame, ToFrame>::camera() const {
48+
return camera_;
49+
}
50+
4551
template<typename FromFrame, typename ToFrame>
4652
Length const& Perspective<FromFrame, ToFrame>::focal() const {
4753
return focal_;

ksp_plugin/interface_planetarium.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Planetarium* __cdecl principia__PlanetariumCreate(
5050
double const focal,
5151
double const field_of_view,
5252
double const inverse_scale_factor,
53+
double const angular_resolution,
5354
XYZ const scaled_space_origin) {
5455
journal::Method<journal::PlanetariumCreate> m({plugin,
5556
sun_world_position,
@@ -60,6 +61,7 @@ Planetarium* __cdecl principia__PlanetariumCreate(
6061
focal,
6162
field_of_view,
6263
inverse_scale_factor,
64+
angular_resolution,
6365
scaled_space_origin});
6466
Renderer const& renderer = CHECK_NOTNULL(plugin)->renderer();
6567

@@ -90,7 +92,7 @@ Planetarium* __cdecl principia__PlanetariumCreate(
9092

9193
Planetarium::Parameters parameters(
9294
/*sphere_radius_multiplier=*/1.0,
93-
/*angular_resolution=*/0.4 * ArcMinute,
95+
angular_resolution * Radian,
9496
field_of_view * Radian);
9597
Perspective<Navigation, Camera> perspective(
9698
world_to_plotting_affine_map *
@@ -151,7 +153,7 @@ void __cdecl principia__PlanetariumPlotFlightPlanSegment(
151153
if (index % 2 == 0 ||
152154
segment->empty() ||
153155
segment->front().time >= plugin->renderer().GetPlottingFrame()->t_min()) {
154-
planetarium->PlotMethod3(
156+
planetarium->PlotMethod4(
155157
*segment,
156158
segment->begin(),
157159
segment->end(),
@@ -183,7 +185,7 @@ void __cdecl principia__PlanetariumPlotPrediction(
183185
*vertex_count = 0;
184186

185187
auto const prediction = plugin->GetVessel(vessel_guid)->prediction();
186-
planetarium->PlotMethod3(
188+
planetarium->PlotMethod4(
187189
*prediction,
188190
prediction->begin(),
189191
prediction->end(),
@@ -239,7 +241,7 @@ void __cdecl principia__PlanetariumPlotPsychohistory(
239241
// time the history will be shorter than desired.
240242
vessel->RequestReanimation(desired_first_time);
241243

242-
planetarium->PlotMethod3(
244+
planetarium->PlotMethod4(
243245
trajectory,
244246
trajectory.lower_bound(desired_first_time),
245247
psychohistory->end(),
@@ -296,7 +298,7 @@ void __cdecl principia__PlanetariumPlotCelestialPastTrajectory(
296298
Instant const first_time =
297299
std::max(desired_first_time, celestial_trajectory.t_min());
298300
Length minimal_distance;
299-
planetarium->PlotMethod3(
301+
planetarium->PlotMethod4(
300302
celestial_trajectory,
301303
first_time,
302304
/*last_time=*/plugin->CurrentTime(),
@@ -354,7 +356,7 @@ void __cdecl principia__PlanetariumPlotCelestialFutureTrajectory(
354356
// No need to request reanimation here because the current time of the
355357
// plugin is necessarily covered.
356358
Length minimal_distance;
357-
planetarium->PlotMethod3(
359+
planetarium->PlotMethod4(
358360
celestial_trajectory,
359361
/*first_time=*/plugin->CurrentTime(),
360362
/*last_time=*/final_time,
@@ -392,7 +394,7 @@ void __cdecl principia__PlanetariumPlotEquipotential(
392394
DiscreteTrajectory<Navigation> const& equipotential =
393395
equipotentials.lines[index];
394396

395-
planetarium->PlotMethod3(
397+
planetarium->PlotMethod4(
396398
equipotential,
397399
equipotential.front().time,
398400
equipotential.back().time,

ksp_plugin/planetarium.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Planetarium::Parameters::Parameters(double const sphere_radius_multiplier,
3030
Angle const& angular_resolution,
3131
Angle const& field_of_view)
3232
: sphere_radius_multiplier_(sphere_radius_multiplier),
33+
angular_resolution_(angular_resolution),
3334
sin²_angular_resolution_(Pow<2>(Sin(angular_resolution))),
3435
tan_angular_resolution_(Tan(angular_resolution)),
3536
tan_field_of_view_(Tan(field_of_view)) {}
@@ -284,6 +285,25 @@ void Planetarium::PlotMethod3(
284285
trajectory, begin_time, last_time, reverse, add_point, max_points);
285286
}
286287

288+
void Planetarium::PlotMethod4(
289+
Trajectory<Barycentric> const& trajectory,
290+
DiscreteTrajectory<Barycentric>::iterator begin,
291+
DiscreteTrajectory<Barycentric>::iterator end,
292+
Instant const& t_max,
293+
bool const reverse,
294+
std::function<void(ScaledSpacePoint const&)> const& add_point,
295+
int max_points) const {
296+
if (begin == end) {
297+
return;
298+
}
299+
auto last = std::prev(end);
300+
auto const begin_time = std::max(begin->time, plotting_frame_->t_min());
301+
auto const last_time =
302+
std::min({last->time, plotting_frame_->t_max(), t_max});
303+
PlotMethod4(
304+
trajectory, begin_time, last_time, reverse, add_point, max_points);
305+
}
306+
287307
std::vector<Sphere<Navigation>> Planetarium::ComputePlottableSpheres(
288308
Instant const& now) const {
289309
SimilarMotion<Barycentric, Navigation> const similar_motion_at_now =

ksp_plugin/planetarium.hpp

+32-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include "base/not_null.hpp"
66
#include "geometry/instant.hpp"
7-
#include "geometry/orthogonal_map.hpp"
87
#include "geometry/perspective.hpp"
98
#include "geometry/r3_element.hpp"
109
#include "geometry/rp2_point.hpp"
@@ -14,7 +13,6 @@
1413
#include "physics/degrees_of_freedom.hpp"
1514
#include "physics/discrete_trajectory.hpp"
1615
#include "physics/ephemeris.hpp"
17-
#include "physics/rigid_motion.hpp"
1816
#include "physics/trajectory.hpp"
1917
#include "quantities/quantities.hpp"
2018

@@ -25,7 +23,6 @@ namespace internal {
2523

2624
using namespace principia::base::_not_null;
2725
using namespace principia::geometry::_instant;
28-
using namespace principia::geometry::_orthogonal_map;
2926
using namespace principia::geometry::_perspective;
3027
using namespace principia::geometry::_r3_element;
3128
using namespace principia::geometry::_rp2_point;
@@ -35,7 +32,6 @@ using namespace principia::ksp_plugin::_frames;
3532
using namespace principia::physics::_degrees_of_freedom;
3633
using namespace principia::physics::_discrete_trajectory;
3734
using namespace principia::physics::_ephemeris;
38-
using namespace principia::physics::_rigid_motion;
3935
using namespace principia::physics::_trajectory;
4036
using namespace principia::quantities::_quantities;
4137

@@ -69,6 +65,7 @@ class Planetarium {
6965

7066
private:
7167
double const sphere_radius_multiplier_;
68+
Angle const angular_resolution_;
7269
double const sin²_angular_resolution_;
7370
double const tan_angular_resolution_;
7471
double const tan_field_of_view_;
@@ -125,7 +122,8 @@ class Planetarium {
125122
Length* minimal_distance = nullptr) const;
126123

127124
// A method similar to PlotMethod2, but which produces a three-dimensional
128-
// trajectory in scaled space instead of projecting and hiding.
125+
// trajectory in scaled space instead of projecting and hiding. It uses the
126+
// apparent angle of the sagitta as the metric to analyse curvature.
129127
void PlotMethod3(
130128
Trajectory<Barycentric> const& trajectory,
131129
DiscreteTrajectory<Barycentric>::iterator begin,
@@ -147,6 +145,29 @@ class Planetarium {
147145
int max_points,
148146
Length* minimal_distance = nullptr) const;
149147

148+
// A method similar to PlotMethod4, but which uses the RMS of the apparent
149+
// distance between the trajectory and line segments.
150+
void PlotMethod4(
151+
Trajectory<Barycentric> const& trajectory,
152+
DiscreteTrajectory<Barycentric>::iterator begin,
153+
DiscreteTrajectory<Barycentric>::iterator end,
154+
Instant const& t_max,
155+
bool reverse,
156+
std::function<void(ScaledSpacePoint const&)> const& add_point,
157+
int max_points) const;
158+
159+
// The same method, operating on the `Trajectory` interface for any frame that
160+
// can be converted to `Navigation`.
161+
template<typename Frame>
162+
void PlotMethod4(
163+
Trajectory<Frame> const& trajectory,
164+
Instant const& first_time,
165+
Instant const& last_time,
166+
bool reverse,
167+
std::function<void(ScaledSpacePoint const&)> const& add_point,
168+
int max_points,
169+
Length* minimal_distance = nullptr) const;
170+
150171
private:
151172
// Computes the coordinates of the spheres that represent the `ephemeris_`
152173
// bodies. These coordinates are in the `plotting_frame_` at time `now`.
@@ -160,6 +181,12 @@ class Planetarium {
160181
DiscreteTrajectory<Barycentric>::iterator begin,
161182
DiscreteTrajectory<Barycentric>::iterator end) const;
162183

184+
// Computes the proper motion (in the astronomical sense) of the given point
185+
// and velocity seen from a frame centered at the origin of `Camera`. This
186+
// is a uniform rotation on a great circle.
187+
AngularVelocity<Navigation> ProperMotion(
188+
DegreesOfFreedom<Navigation> const& degrees_of_freedom) const;
189+
163190
Parameters const parameters_;
164191
Perspective<Navigation, Camera> const perspective_;
165192
not_null<Ephemeris<Barycentric> const*> const ephemeris_;

0 commit comments

Comments
 (0)