-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathmain.cpp
More file actions
142 lines (118 loc) · 3.71 KB
/
Copy pathmain.cpp
File metadata and controls
142 lines (118 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// This code is based on Jet framework.
// Copyright (c) 2018 Doyub Kim
// CubbyFlow is voxel-based fluid simulation engine for computer games.
// Copyright (c) 2020 CubbyFlow Team
// Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
// AI Part: Dongheon Cho, Minseo Kim
// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <algorithm>
#include <array>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <string>
#include <thread>
const size_t BUFFER_SIZE = 80;
const std::string GRAY_SCALE_TABLE = " .:-=+*#%@";
const size_t GRAY_SCALE_TABLE_SIZE = GRAY_SCALE_TABLE.length();
void UpdateWave(const double timeInterval, double* x, double* speed)
{
(*x) += timeInterval * (*speed);
// Boundary reflection
if ((*x) > 1.0)
{
(*speed) *= -1.0;
(*x) = 1.0 + timeInterval * (*speed);
}
else if ((*x) < 0.0)
{
(*speed) *= -1.0;
(*x) = timeInterval * (*speed);
}
}
void AccumulateWaveToHeightField(const double x, const double waveLength,
const double maxHeight,
std::array<double, BUFFER_SIZE>* heightField)
{
const double quarterWaveLength = 0.25 * waveLength;
const int start = static_cast<int>((x - quarterWaveLength) * BUFFER_SIZE);
const int end = static_cast<int>((x + quarterWaveLength) * BUFFER_SIZE);
for (int i = start; i < end; ++i)
{
int iNew = i;
if (i < 0)
{
iNew = -i - 1;
}
else if (i >= static_cast<int>(BUFFER_SIZE))
{
iNew = 2 * BUFFER_SIZE - i - 1;
}
const double distance = fabs((i + 0.5) / BUFFER_SIZE - x);
const double height =
maxHeight * 0.5 *
(cos(std::min(distance * M_PI / quarterWaveLength, M_PI)) + 1.0);
(*heightField)[iNew] += height;
}
}
void Draw(const std::array<double, BUFFER_SIZE>& heightField)
{
std::string buffer(BUFFER_SIZE, ' ');
// Convert height field to grayscale
for (size_t i = 0; i < BUFFER_SIZE; ++i)
{
const double height = heightField[i];
const size_t tableIndex =
std::min(static_cast<size_t>(floor(GRAY_SCALE_TABLE_SIZE * height)),
GRAY_SCALE_TABLE_SIZE - 1);
buffer[i] = GRAY_SCALE_TABLE[tableIndex];
}
// Clear old prints
for (size_t i = 0; i < BUFFER_SIZE; ++i)
{
printf("\b");
}
// Draw new buffer
printf("%s", buffer.c_str());
fflush(stdout);
}
int main()
{
const double waveLengthX = 0.8;
const double waveLengthY = 1.2;
const double maxHeightX = 0.5;
const double maxHeightY = 0.4;
double x = 0.0;
double y = 1.0;
double speedX = 1.0;
double speedY = -0.5;
const int fps = 100;
const double timeInterval = 1.0 / fps;
std::array<double, BUFFER_SIZE> heightField;
for (int i = 0; i < 1000; ++i)
{
// March through time
UpdateWave(timeInterval, &x, &speedX);
UpdateWave(timeInterval, &y, &speedY);
// Clear height field
for (double& height : heightField)
{
height = 0.0;
}
// Accumulate waves for each center point
AccumulateWaveToHeightField(x, waveLengthX, maxHeightX, &heightField);
AccumulateWaveToHeightField(y, waveLengthY, maxHeightY, &heightField);
// Draw height field
Draw(heightField);
// Wait
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / fps));
}
printf("\n");
fflush(stdout);
return 0;
}