Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
//"Siv3D January 2016"を使用
# include <Siv3D.hpp>
using namespace std;
#define M 6 //ループ回数
#define N 4097 //点の数
#define P int(pow(4, M - i -1))
#define Q int(pow(4, M - i))
#define P0 j * Q
#define P1 j * Q + 1 * P
#define P2 j * Q + 2 * P
#define P3 j * Q + 3 * P
#define P4 j * Q + 4 * P
//ラジアン
double const rad = 60. * Pi / 180.;
//配列
double x[N];
double y[N];
// 線を作成
LineString lines0(2 * 3, Vec2(0, 0));
LineString lines1(5 * 3, Vec2(0, 0));
LineString lines2(17 * 3, Vec2(0, 0));
LineString lines3(65 * 3, Vec2(0, 0));
LineString lines4(257 * 3, Vec2(0, 0));
LineString lines5(1025 * 3, Vec2(0, 0));
LineString lines6(4097 * 3, Vec2(0, 0));
void f(double x1, double y1, double x2, double y2, double x[], double y[]);
void g(LineString* lines,int a, int b, int c);
void h(double x[], double y[]);
void i(int c);
void Main()
{
// 背景色を 白 に設定する
Graphics::SetBackground(Palette::White);
f(480., 110., 170., 110.,x,y);//一つ目のコッホ曲線
i(0);//
h(x, y);//回転
i(1);
h(x, y);
i(2);
int sign=1;
const Font font(12);
Rect rect1(110, 1, 440, 450);
Rect rect2(120, 10, 420, 400);
while (System::Update())
{
rect1.draw({ 245,245,245 });
rect1.drawFrame(0, 1, { 145,145,145 });
rect2.draw();
rect2.drawFrame(0, 1, { 145,145,145 });
switch (sign) {
case 1:
lines0.draw(1, Palette::Blue); break;
case 2:
lines1.draw(1, Palette::Blue); break;
case 3:
lines2.draw(1, Palette::Blue); break;
case 4:
lines3.draw(1, Palette::Blue); break;
case 5:
lines4.draw(1, Palette::Blue); break;
case 6:
lines5.draw(1, Palette::Blue); break;
case 7:
lines6.draw(1, Palette::Blue); break;
}
font(L"ステップ6までを示すアニメーション。").draw(150,420, Palette::Black);
if (System::FrameCount() % 60 == 0) {
sign++;
if (sign == 8) { sign = 1; }
}
}
}
//一つ目のコッホ曲線
void f(double x1, double y1, double x2, double y2,double x[], double y[]) {
x[0] = x1;
y[0] = y1;
x[N - 1] = x2;
y[N - 1] = y2;
//ループ
for (int i = 0; i < M; i++) {
//この時点での直線の数だけ処理を繰り返す
for (int j = 0; j < pow(4, i); j++) {
//三等分
x[P1] = (2. * x[P0] + x[P4]) / 3;
y[P1] = (2. * y[P0] + y[P4]) / 3;
x[P3] = (x[P0] + 2 * x[P4]) / 3;
y[P3] = (y[P0] + 2 * y[P4]) / 3;
//回転行列:上で求めた2点のうち、1点を原点と見立てて60度回転
x[P2] = (x[P3] - x[P1]) * cos(rad) - (y[P3] - y[P1]) * sin(rad) + x[P1];
y[P2] = (x[P3] - x[P1]) * sin(rad) + (y[P3] - y[P1]) * cos(rad) + y[P1];
}
}
}
//
void g(LineString* lines,int a,int b, int c) {
for (int i = 0; i < a; i++)
{
lines->point(i + a * c).set(x[i * int(pow(4, b))], y[i * int(pow(4, b))]);
}
}
//二つ目、三つ目のコッホ曲線
void h(double x[], double y[]) {
//回転行列
double xn[N];
double yn[N];
xn[0] = x[0];
yn[0] = y[0];
for (int i = 1; i < N; i++) {
xn[i] = (x[i] - x[0]) * cos(-rad) - (y[i] - y[0]) * sin(-rad) + x[0];
yn[i] = (x[i] - x[0]) * sin(-rad) + (y[i] - y[0]) * cos(-rad) + y[0];
}
for (int i = 0; i < N; i++) {
x[i] = xn[i];
y[i] = yn[i];
}
for (int i = 0; i < N - 1; i++) {
xn[i] = (x[i] - x[N - 1]) * cos(-rad) - (y[i] - y[N - 1]) * sin(-rad) + x[N - 1];
yn[i] = (x[i] - x[N - 1]) * sin(-rad) + (y[i] - y[N - 1]) * cos(-rad) + y[N - 1];
}
for (int i = 0; i < N; i++) {
x[i] = xn[i];
y[i] = yn[i];
}
}
void i(int c) {
g(&lines0, 2, 6, c);
g(&lines1, 5, 5, c);
g(&lines2, 17, 4, c);
g(&lines3, 65, 3, c);
g(&lines4, 257, 2, c);
g(&lines5, 1025, 1, c);
g(&lines6, 4097, 0, c);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment