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

回答編集履歴

2

コード修正

2020/02/19 03:48

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -1,58 +1,101 @@
1
1
  ざっくり見た感じですが, fractale の do-while 内では始点終点の2つを"直線"として取り出しているのですから, 計算の結果は4本の"直線"の各始点終点である計8つの点を入れないといけないのではないでしょうか.
2
2
 
3
+ 編集1
3
4
  ---
4
5
  表示が面倒になってしまうようですので, yudedako67 さんの回答のようにキューに各座標を1つだけ入れる形で再帰のコードにしてみました.
5
6
  c++ は大分前に勉強したのみですのでコードの質はご容赦ください.
6
- 一応 [paiza.io](https://paiza.io/ja/) で実行は確認しましたが, 表示される値が一部変なので, 計算式に問題はあるかと思います(そこまでは修正していません).
7
+ 一応 [paiza.io](https://paiza.io/ja/) で実行は確認しましたが, 表示される値が一部変なので, 計算式に問題はあるかと思います.
8
+
9
+ 編集2
10
+ ---
11
+
12
+ テスト用にコードを修正しました.
7
13
  ```c++
8
14
  #include <iostream>
9
15
  #include <queue>
10
- #include <vector>
11
- #include <algorithm>
12
16
  #include <cmath>
13
17
  #include <iomanip>
18
+ #include <bits/stdc++.h>
14
19
 
15
20
  using namespace std;
16
21
 
17
- queue<pair<long double, long double>> p;
18
- const long double h = sqrt(3)/2.0;
22
+ const long double H = sqrt(3)/2.0;
19
23
 
20
- void fractale(int n) {
24
+ void fractal(queue<pair<double, double>>& q, int n) {
21
25
  if(n <= 0) return;
22
26
 
23
- pair<long double, long double> l, r, temp;
27
+ pair<double, double> l, r, t;
24
- int size = p.size();
28
+ int size = q.size();
25
29
  for(int i=0; i<size-1; i++) {
26
- l = p.front(); p.pop();
30
+ l = q.front(); q.pop();
27
- r = p.front();
31
+ r = q.front();
32
+
33
+ double w = r.first - l.first;
34
+ double h = r.second - l.second;
35
+ double theta = atan2(h, w);
36
+ double length = sqrt(h*h + w*w);
28
37
 
29
- p.push(l);
38
+ q.push(l);
30
- temp = make_pair(l.first+(r.first-l.first)/3.0, l.second+(r.second-l.second)/3.0);
39
+ t = make_pair(l.first+w/3.0, l.second+h/3.0);
31
- p.push(temp);
40
+ q.push(t);
32
- long double theta = atan2(r.second-l.second, r.first-l.first);
33
- long double leng = sqrt((r.second-l.second)*(r.second-l.second)+(r.first-l.first)*(r.first-l.first));
34
- temp = make_pair(l.first+(r.first-l.first)/2.0+leng*h*sin(theta)/3.0, l.second+(r.second-l.second)/2.0+leng*h*cos(theta)/3.0);
41
+ t = make_pair(l.first+w/2.0+length*H*sin(theta)/3.0, l.second+h/2.0+length*H*cos(theta)/3.0); //orig
42
+ //t = make_pair(t.first+length*cos(theta+M_PI/3.0)/3.0, t.second+length*sin(theta+M_PI/3.0)/3.0);
35
- p.push(temp);
43
+ q.push(t);
36
- temp = make_pair(l.first+2*(r.first-l.first)/3.0, l.second+2*(r.second-l.second)/3.0);
44
+ t = make_pair(l.first+2*w/3.0, l.second+2*h/3.0);
37
- p.push(temp);
45
+ q.push(t);
38
46
  }
39
- r = p.front(); p.pop();
47
+ r = q.front(); q.pop();
40
- p.push(r);
48
+ q.push(r);
41
-
49
+
42
- fractale(--n);
50
+ fractal(q, --n);
43
51
  }
52
+ void test(int n, const char* ex) {
53
+ cout << "test: n=" << n << endl;
44
54
 
45
- int main(){
55
+ queue<pair<double, double>> q;
46
- p.push(make_pair(0.0, 0.0));
56
+ q.push(make_pair(0.0, 0.0));
47
- p.push(make_pair(100.0, 0.0));
57
+ q.push(make_pair(100.0, 0.0));
48
58
 
49
- int n;
50
- cin >> n;
51
- fractale(n);
59
+ fractal(q, n);
52
60
 
61
+ ostringstream oss;
53
- cout << fixed << setprecision(10);
62
+ oss << fixed << setprecision(8);
54
- for (; !p.empty(); p.pop()){
63
+ for (; !q.empty(); q.pop()){
55
- cout << p.front().first << " " << p.front().second << endl;
64
+ oss << q.front().first << " " << q.front().second << "\n";
56
65
  }
66
+
67
+ if(string(ex).compare(oss.str()) == 0) {
68
+ cout << "=== OK ===" << endl;
69
+ } else {
70
+ cout << "*** NG ***" << endl;
71
+ cout << oss.str() << flush;
72
+ }
57
73
  }
74
+ int main(){
75
+ test(1,
76
+ "0.00000000 0.00000000\n"
77
+ "33.33333333 0.00000000\n"
78
+ "50.00000000 28.86751346\n"
79
+ "66.66666667 0.00000000\n"
80
+ "100.00000000 0.00000000\n");
81
+
82
+ test(2,
83
+ "0.00000000 0.00000000\n"
84
+ "11.11111111 0.00000000\n"
85
+ "16.66666667 9.62250449\n"
86
+ "22.22222222 0.00000000\n"
87
+ "33.33333333 0.00000000\n"
88
+ "38.88888889 9.62250449\n"
89
+ "33.33333333 19.24500897\n"
90
+ "44.44444444 19.24500897\n"
91
+ "50.00000000 28.86751346\n"
92
+ "55.55555556 19.24500897\n"
93
+ "66.66666667 19.24500897\n"
94
+ "61.11111111 9.62250449\n"
95
+ "66.66666667 0.00000000\n"
96
+ "77.77777778 0.00000000\n"
97
+ "83.33333333 9.62250449\n"
98
+ "88.88888889 0.00000000\n"
99
+ "100.00000000 0.00000000\n");
100
+ }
58
101
  ```

1

コード追加

2020/02/19 03:48

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -1,1 +1,58 @@
1
- ざっくり見た感じですが, fractale の do-while 内では始点終点の2つを"直線"として取り出しているのですから, 計算の結果は4本の"直線"の各始点終点である計8つの点を入れないといけないのではないでしょうか.
1
+ ざっくり見た感じですが, fractale の do-while 内では始点終点の2つを"直線"として取り出しているのですから, 計算の結果は4本の"直線"の各始点終点である計8つの点を入れないといけないのではないでしょうか.
2
+
3
+ ---
4
+ 表示が面倒になってしまうようですので, yudedako67 さんの回答のようにキューに各座標を1つだけ入れる形で再帰のコードにしてみました.
5
+ c++ は大分前に勉強したのみですのでコードの質はご容赦ください.
6
+ 一応 [paiza.io](https://paiza.io/ja/) で実行は確認しましたが, 表示される値が一部変なので, 計算式に問題はあるかと思います(そこまでは修正していません).
7
+ ```c++
8
+ #include <iostream>
9
+ #include <queue>
10
+ #include <vector>
11
+ #include <algorithm>
12
+ #include <cmath>
13
+ #include <iomanip>
14
+
15
+ using namespace std;
16
+
17
+ queue<pair<long double, long double>> p;
18
+ const long double h = sqrt(3)/2.0;
19
+
20
+ void fractale(int n) {
21
+ if(n <= 0) return;
22
+
23
+ pair<long double, long double> l, r, temp;
24
+ int size = p.size();
25
+ for(int i=0; i<size-1; i++) {
26
+ l = p.front(); p.pop();
27
+ r = p.front();
28
+
29
+ p.push(l);
30
+ temp = make_pair(l.first+(r.first-l.first)/3.0, l.second+(r.second-l.second)/3.0);
31
+ p.push(temp);
32
+ long double theta = atan2(r.second-l.second, r.first-l.first);
33
+ long double leng = sqrt((r.second-l.second)*(r.second-l.second)+(r.first-l.first)*(r.first-l.first));
34
+ temp = make_pair(l.first+(r.first-l.first)/2.0+leng*h*sin(theta)/3.0, l.second+(r.second-l.second)/2.0+leng*h*cos(theta)/3.0);
35
+ p.push(temp);
36
+ temp = make_pair(l.first+2*(r.first-l.first)/3.0, l.second+2*(r.second-l.second)/3.0);
37
+ p.push(temp);
38
+ }
39
+ r = p.front(); p.pop();
40
+ p.push(r);
41
+
42
+ fractale(--n);
43
+ }
44
+
45
+ int main(){
46
+ p.push(make_pair(0.0, 0.0));
47
+ p.push(make_pair(100.0, 0.0));
48
+
49
+ int n;
50
+ cin >> n;
51
+ fractale(n);
52
+
53
+ cout << fixed << setprecision(10);
54
+ for (; !p.empty(); p.pop()){
55
+ cout << p.front().first << " " << p.front().second << endl;
56
+ }
57
+ }
58
+ ```