回答編集履歴

2

コード修正

2020/02/19 03:48

投稿

jimbe
jimbe

スコア13209

test CHANGED
@@ -2,13 +2,25 @@
2
2
 
3
3
 
4
4
 
5
+ 編集1
6
+
5
7
  ---
6
8
 
7
9
  表示が面倒になってしまうようですので, yudedako67 さんの回答のようにキューに各座標を1つだけ入れる形で再帰のコードにしてみました.
8
10
 
9
11
  c++ は大分前に勉強したのみですのでコードの質はご容赦ください.
10
12
 
11
- 一応 [paiza.io](https://paiza.io/ja/) で実行は確認しましたが, 表示される値が一部変なので, 計算式に問題はあるかと思います(そこまでは修正していません).
13
+ 一応 [paiza.io](https://paiza.io/ja/) で実行は確認しましたが, 表示される値が一部変なので, 計算式に問題はあるかと思います.
14
+
15
+
16
+
17
+ 編集2
18
+
19
+ ---
20
+
21
+
22
+
23
+ テスト用にコードを修正しました.
12
24
 
13
25
  ```c++
14
26
 
@@ -16,99 +28,173 @@
16
28
 
17
29
  #include <queue>
18
30
 
19
- #include <vector>
20
-
21
- #include <algorithm>
22
-
23
31
  #include <cmath>
24
32
 
25
33
  #include <iomanip>
26
34
 
35
+ #include <bits/stdc++.h>
36
+
27
37
 
28
38
 
29
39
  using namespace std;
30
40
 
31
41
 
32
42
 
33
- queue<pair<long double, long double>> p;
34
-
35
- const long double h = sqrt(3)/2.0;
43
+ const long double H = sqrt(3)/2.0;
36
-
37
-
38
-
44
+
45
+
46
+
39
- void fractale(int n) {
47
+ void fractal(queue<pair<double, double>>& q, int n) {
40
48
 
41
49
  if(n <= 0) return;
42
50
 
43
51
 
44
52
 
45
- pair<long double, long double> l, r, temp;
53
+ pair<double, double> l, r, t;
46
-
54
+
47
- int size = p.size();
55
+ int size = q.size();
48
56
 
49
57
  for(int i=0; i<size-1; i++) {
50
58
 
51
- l = p.front(); p.pop();
59
+ l = q.front(); q.pop();
52
-
60
+
53
- r = p.front();
61
+ r = q.front();
62
+
63
+
64
+
54
-
65
+ double w = r.first - l.first;
66
+
55
-
67
+ double h = r.second - l.second;
68
+
56
-
69
+ double theta = atan2(h, w);
70
+
71
+ double length = sqrt(h*h + w*w);
72
+
73
+
74
+
57
- p.push(l);
75
+ q.push(l);
58
-
76
+
59
- temp = make_pair(l.first+(r.first-l.first)/3.0, l.second+(r.second-l.second)/3.0);
77
+ t = make_pair(l.first+w/3.0, l.second+h/3.0);
60
-
78
+
61
- p.push(temp);
79
+ q.push(t);
62
-
63
- long double theta = atan2(r.second-l.second, r.first-l.first);
80
+
64
-
65
- long double leng = sqrt((r.second-l.second)*(r.second-l.second)+(r.first-l.first)*(r.first-l.first));
66
-
67
- 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);
81
+ 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
82
+
68
-
83
+ //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);
84
+
69
- p.push(temp);
85
+ q.push(t);
70
-
86
+
71
- temp = make_pair(l.first+2*(r.first-l.first)/3.0, l.second+2*(r.second-l.second)/3.0);
87
+ t = make_pair(l.first+2*w/3.0, l.second+2*h/3.0);
72
-
88
+
73
- p.push(temp);
89
+ q.push(t);
74
90
 
75
91
  }
76
92
 
77
- r = p.front(); p.pop();
93
+ r = q.front(); q.pop();
78
-
94
+
79
- p.push(r);
95
+ q.push(r);
80
-
81
-
82
-
96
+
97
+
98
+
83
- fractale(--n);
99
+ fractal(q, --n);
84
100
 
85
101
  }
86
102
 
87
-
103
+ void test(int n, const char* ex) {
104
+
105
+ cout << "test: n=" << n << endl;
106
+
107
+
108
+
109
+ queue<pair<double, double>> q;
110
+
111
+ q.push(make_pair(0.0, 0.0));
112
+
113
+ q.push(make_pair(100.0, 0.0));
114
+
115
+
116
+
117
+ fractal(q, n);
118
+
119
+
120
+
121
+ ostringstream oss;
122
+
123
+ oss << fixed << setprecision(8);
124
+
125
+ for (; !q.empty(); q.pop()){
126
+
127
+ oss << q.front().first << " " << q.front().second << "\n";
128
+
129
+ }
130
+
131
+
132
+
133
+ if(string(ex).compare(oss.str()) == 0) {
134
+
135
+ cout << "=== OK ===" << endl;
136
+
137
+ } else {
138
+
139
+ cout << "*** NG ***" << endl;
140
+
141
+ cout << oss.str() << flush;
142
+
143
+ }
144
+
145
+ }
88
146
 
89
147
  int main(){
90
148
 
149
+ test(1,
150
+
91
- p.push(make_pair(0.0, 0.0));
151
+ "0.00000000 0.00000000\n"
152
+
92
-
153
+ "33.33333333 0.00000000\n"
154
+
155
+ "50.00000000 28.86751346\n"
156
+
157
+ "66.66666667 0.00000000\n"
158
+
159
+ "100.00000000 0.00000000\n");
160
+
161
+
162
+
163
+ test(2,
164
+
165
+ "0.00000000 0.00000000\n"
166
+
93
- p.push(make_pair(100.0, 0.0));
167
+ "11.11111111 0.00000000\n"
94
-
95
-
96
-
97
- int n;
168
+
98
-
99
- cin >> n;
169
+ "16.66666667 9.62250449\n"
100
-
170
+
101
- fractale(n);
171
+ "22.22222222 0.00000000\n"
172
+
102
-
173
+ "33.33333333 0.00000000\n"
174
+
103
-
175
+ "38.88888889 9.62250449\n"
176
+
104
-
177
+ "33.33333333 19.24500897\n"
178
+
179
+ "44.44444444 19.24500897\n"
180
+
181
+ "50.00000000 28.86751346\n"
182
+
183
+ "55.55555556 19.24500897\n"
184
+
185
+ "66.66666667 19.24500897\n"
186
+
187
+ "61.11111111 9.62250449\n"
188
+
189
+ "66.66666667 0.00000000\n"
190
+
191
+ "77.77777778 0.00000000\n"
192
+
193
+ "83.33333333 9.62250449\n"
194
+
195
+ "88.88888889 0.00000000\n"
196
+
105
- cout << fixed << setprecision(10);
197
+ "100.00000000 0.00000000\n");
106
-
107
- for (; !p.empty(); p.pop()){
108
-
109
- cout << p.front().first << " " << p.front().second << endl;
110
-
111
- }
112
198
 
113
199
  }
114
200
 

1

コード追加

2020/02/19 03:48

投稿

jimbe
jimbe

スコア13209

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