質問するログイン新規登録

回答編集履歴

9

rangesは結局使わなかったので削除。

2025/08/07 17:14

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -20,7 +20,6 @@
20
20
  #include <numeric> // accumulate
21
21
  #include <algorithm> // reverse
22
22
  #include <utility> // pair
23
- #include <ranges> // C++20以上で必要(オプション)
24
23
 
25
24
  using Vec2 = std::pair<double, double>;
26
25
  using Record = std::tuple<double, Vec2, Vec2>; // (t, r, v)

8

コードの計算過程の出力を、原作の意図通り、0.1秒毎出力へと変更

2025/08/06 15:52

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -77,8 +77,10 @@
77
77
  std::cout << std::fixed << std::setprecision(10);
78
78
  std::reverse(data.begin(), data.end());
79
79
  for (const auto& [t, r, v] : data) {
80
+ if (std::fmod(t / 0.01, 10) < 1e-9) { // t が 0.1, 0.2, 0.3 ... のときだけ出力
80
- std::cout << t << ", " << r.first << ", " << r.second
81
+ std::cout << t << ", " << r.first << ", " << r.second
81
- << ", " << v.first << ", " << v.second << '\n';
82
+ << ", " << v.first << ", " << v.second << '\n';
83
+ }
82
84
  }
83
85
 
84
86
  const auto& [tf, rf, vf] = data.back();

7

注釈を修正

2025/08/06 14:14

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -235,5 +235,5 @@
235
235
 
236
236
  注1: [```std::setprecition```](https://cpprefjp.github.io/reference/iomanip/setprecision.html)ではそこに書かれてる通り、「浮動小数点数を出力する精度を設定」してて、[```std::fixed```](https://cpprefjp.github.io/reference/ios/fixed.html)では、「浮動小数点数を固定小数点表記で入出力することを指示」しているだけだ。
237
237
 
238
- 注2: なお、オリジナルのコードでもx座標の初期値に```cos(1/2 * Π)```が使われてるんで、は水平方向だと位置情報は0のまんま、となると思う。
238
+ 注2: なお、オリジナルのコードでも速度vのx成分の初期値に```cos(1/2 * Π)```が使われてるんで、全履歴は水平方向だと位置情報は0のまんま、速度のx成分も0のまんま、となると思う。
239
- 結果、時間経過があってもxは全て0のまま、速度vのx成分も0のまま、となって、事実上このシミュレーションは鉛直方向への「投げ上げ」って事になるんじゃなかろうか。
239
+ 結果、事実上このシミュレーションは鉛直方向への「投げ上げ」って事になるんじゃなかろうか。

6

マークダウン修正

2025/08/05 21:56

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -125,7 +125,7 @@
125
125
  繰り返すけど、多々の情報を**纏めて扱う**ってのはモダンなプログラミングでは重要な概念で、STLを備えたC++はその「モダンなプログラミング」に片足突っ込んでいて、その辺実は古典的なCとは全く違う思想を持っている。
126
126
  この後それを知ることとなる。
127
127
 
128
- 次はユーティリティ**arange**だ。
128
+ 次はユーティリティ```arange```だ。
129
129
 
130
130
  ```C++
131
131
  std::vector<double> arange(double start, double end, double step) {

5

本文修正

2025/08/05 21:55

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -107,7 +107,7 @@
107
107
  ```
108
108
 
109
109
  として二次元ベクトル、```Vec2```型、ってのを定義している。
110
- 厳密に言うと、```Vec2```型を[```std::pair```](https://cpprefjp.github.io/reference/utility/pair.html)への[エイリアス](https://e-words.jp/w/%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9.html)として用いる、と言う事だ。
110
+ 厳密に言うと、```Vec2```型を[```std::pair<double, double>```](https://cpprefjp.github.io/reference/utility/pair.html)への[エイリアス](https://e-words.jp/w/%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9.html)として用いる、と言う事だ。
111
111
  これにより```r = (x, y)```とか```v = (vx, vy)```みたいな、**より物理学らしい**表現が可能となる。
112
112
 
113
113
  もう一つは```Record```型の定義だ。

4

時間列の範囲指定ミスを修正

2025/08/05 21:42

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -65,7 +65,7 @@
65
65
  };
66
66
 
67
67
  std::vector<Record> initial = { std::make_tuple(t_0, r_0, v_0) };
68
- std::vector<double> steps = arange(t_0 + h, t_n + h, h);
68
+ std::vector<double> steps = arange(t_0 + h, t_n, h);
69
69
 
70
70
  std::vector<Record> data = std::accumulate(
71
71
  steps.begin(), steps.end(), initial,

3

係数を2Mで割るのを忘れてた・・・・・・orz

2025/08/05 21:35

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -43,7 +43,7 @@
43
43
 
44
44
  std::vector<Record> foo(const std::vector<Record>& acc, double s) {
45
45
  const auto& [t, r, v] = acc.front(); // 先頭が最新状態
46
- double coeff = - rho * Cd * S * std::sqrt(v.first * v.first + v.second * v.second);
46
+ double coeff = - rho * Cd * S * std::sqrt(v.first * v.first + v.second * v.second) / (2 * M);
47
47
  Vec2 r_new = {
48
48
  r.first + h * v.first,
49
49
  r.second + h * v.second

2

計算結果上の注釈を付けた。

2025/08/05 18:51

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -233,4 +233,7 @@
233
233
  あとは出力するだけ、となる。
234
234
  おしまい。
235
235
 
236
- : [```std::setprecition```](https://cpprefjp.github.io/reference/iomanip/setprecision.html)ではそこに書かれてる通り、「浮動小数点数を出力する精度を設定」してて、[```std::fixed```](https://cpprefjp.github.io/reference/ios/fixed.html)では、「浮動小数点数を固定小数点表記で入出力することを指示」しているだけだ。
236
+ 注1: [```std::setprecition```](https://cpprefjp.github.io/reference/iomanip/setprecision.html)ではそこに書かれてる通り、「浮動小数点数を出力する精度を設定」してて、[```std::fixed```](https://cpprefjp.github.io/reference/ios/fixed.html)では、「浮動小数点数を固定小数点表記で入出力することを指示」しているだけだ。
237
+
238
+ 注2: なお、オリジナルのコードでもx座標の初期値に```cos(1/2 * Π)```が使われてるんで、実は水平方向だと位置情報は0のまんま、となると思う。
239
+ 結果、時間経過があってもxは全て0のまま、速度vのx成分も0のまま、となって、事実上このシミュレーションは鉛直方向への「投げ上げ」って事になるんじゃなかろうか。

1

マークダウンを修正

2025/08/05 18:36

投稿

cametan
cametan

スコア161

answer CHANGED
@@ -227,7 +227,7 @@
227
227
 
228
228
  ```
229
229
 
230
- 時間列が```end```に到達するまで、```std::accumulate```は関数```foo``を利用しつつ```initial```を加工していく。最終的には時間列の長さ(この問題の場合は200)に合わせて古い順から並んだ200個の計算結果(```(t, r, v)```)が詰め込まれたシーケンスを入手する。
230
+ 時間列が```end```に到達するまで、```std::accumulate```は関数```foo```を利用しつつ```initial```を加工していく。最終的には時間列の長さ(この問題の場合は200)に合わせて古い順から並んだ200個の計算結果(```(t, r, v)```)が詰め込まれたシーケンスを入手する。
231
231
  これでオイラー法は終了、だ。
232
232
 
233
233
  あとは出力するだけ、となる。