Last active
April 4, 2017 06:02
-
-
Save lpereira/8bc64bf9796984b7868b8255d1692d59 to your computer and use it in GitHub Desktop.
surface.go from chapter 3 of "The Go Programming Language"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace io { | |
struct Reader { | |
virtual std::tuple<int, moku::error> Read(moku::slice<uint8_t> p) = 0; | |
}; | |
struct Writer { | |
virtual std::tuple<int, moku::error> Write(moku::slice<uint8_t> p) = 0; | |
}; | |
} // namespace io | |
namespace fmt { | |
moku::error Errorf(std::string format, moku::slice<moku::empty_interface> a); | |
struct Formatter { | |
virtual void Format(State f, int32_t c) = 0; | |
}; | |
std::tuple<int, moku::error> Fprint(Writer w, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Fprintf(Writer w, std::string format, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Fprintln(Writer w, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Fscan(Reader r, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Fscanf(Reader r, std::string format, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Fscanln(Reader r, | |
moku::slice<moku::empty_interface> a); | |
struct GoStringer { | |
virtual std::string GoString() = 0; | |
}; | |
std::tuple<int, moku::error> Print(moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Printf(std::string format, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Println(moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Scan(moku::slice<moku::empty_interface> a); | |
struct ScanState { | |
virtual std::tuple<int, bool> Width() = 0; | |
virtual moku::error UnreadRune() = 0; | |
virtual std::tuple<moku::slice<uint8_t>, moku::error> | |
Token(bool skipSpace, std::function<bool(int32_t)> f) = 0; | |
virtual void SkipSpace() = 0; | |
virtual std::tuple<int32_t, int, moku::error> ReadRune() = 0; | |
virtual std::tuple<int, moku::error> Read(moku::slice<uint8_t> buf) = 0; | |
}; | |
std::tuple<int, moku::error> Scanf(std::string format, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Scanln(moku::slice<moku::empty_interface> a); | |
struct Scanner { | |
virtual moku::error Scan(ScanState state, int32_t verb) = 0; | |
}; | |
std::string Sprint(moku::slice<moku::empty_interface> a); | |
std::string Sprintf(std::string format, moku::slice<moku::empty_interface> a); | |
std::string Sprintln(moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Sscan(std::string str, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Sscanf(std::string str, std::string format, | |
moku::slice<moku::empty_interface> a); | |
std::tuple<int, moku::error> Sscanln(std::string str, | |
moku::slice<moku::empty_interface> a); | |
struct State { | |
virtual std::tuple<int, moku::error> Write(moku::slice<uint8_t> b) = 0; | |
virtual std::tuple<int, bool> Width() = 0; | |
virtual std::tuple<int, bool> Precision() = 0; | |
virtual bool Flag(int c) = 0; | |
}; | |
struct Stringer { | |
virtual std::string String() = 0; | |
}; | |
void init(); | |
} // namespace fmt | |
namespace math { | |
double Abs(double x); | |
double Acos(double x); | |
double Acosh(double x); | |
double Asin(double x); | |
double Asinh(double x); | |
double Atan(double x); | |
double Atan2(double y, double x); | |
double Atanh(double x); | |
double Cbrt(double x); | |
double Ceil(double x); | |
double Copysign(double x, double y); | |
double Cos(double x); | |
double Cosh(double x); | |
double Dim(double x, double y); | |
constexpr float E{2.71828}; | |
double Erf(double x); | |
double Erfc(double x); | |
double Exp(double x); | |
double Exp2(double x); | |
double Expm1(double x); | |
uint32_t Float32bits(float f); | |
float Float32frombits(uint32_t b); | |
uint64_t Float64bits(double f); | |
double Float64frombits(uint64_t b); | |
double Floor(double x); | |
std::tuple<double, int> Frexp(double f); | |
double Gamma(double x); | |
double Hypot(double p, double q); | |
int Ilogb(double x); | |
double Inf(int sign); | |
bool IsInf(double f, int sign); | |
bool IsNaN(double f); | |
double J0(double x); | |
double J1(double x); | |
double Jn(int n, double x); | |
double Ldexp(double frac, int exp); | |
std::tuple<double, int> Lgamma(double x); | |
constexpr float Ln10{2.30259}; | |
constexpr float Ln2{0.693147}; | |
double Log(double x); | |
double Log10(double x); | |
constexpr float Log10E{0.434294}; | |
double Log1p(double x); | |
double Log2(double x); | |
constexpr float Log2E{1.4427}; | |
double Logb(double x); | |
double Max(double x, double y); | |
constexpr float MaxFloat32{340282346638528859811704183484516925440}; | |
constexpr float MaxFloat64{ | |
179769313486231570814527423731704356798100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001726091719747851502452248840877809013992353692576760003314411346346787114201583914540245118557675136988317857687302483414838584368727290187675497882714112}; | |
constexpr int MaxInt16{32767}; | |
constexpr int MaxInt32{2147483647}; | |
constexpr int MaxInt64{9223372036854775807}; | |
constexpr int MaxInt8{127}; | |
constexpr int MaxUint16{65535}; | |
constexpr int MaxUint32{4294967295}; | |
constexpr int MaxUint64{18446744073709551615}; | |
constexpr int MaxUint8{255}; | |
double Min(double x, double y); | |
constexpr int MinInt16{-32768}; | |
constexpr int MinInt32{-2147483648}; | |
constexpr int MinInt64{-9223372036854775808}; | |
constexpr int MinInt8{-128}; | |
double Mod(double x, double y); | |
std::tuple<double, double> Modf(double f); | |
double NaN(); | |
double Nextafter(double x, double y); | |
float Nextafter32(float x, float y); | |
constexpr float Phi{1.61803}; | |
constexpr float Pi{3.14159}; | |
double Pow(double x, double y); | |
double Pow10(int e); | |
double Remainder(double x, double y); | |
bool Signbit(double x); | |
double Sin(double x); | |
std::tuple<double, double> Sincos(double x); | |
double Sinh(double x); | |
constexpr float SmallestNonzeroFloat32{1.4013e-45}; | |
constexpr float SmallestNonzeroFloat64{4.94066e-324}; | |
double Sqrt(double x); | |
constexpr float Sqrt2{1.41421}; | |
constexpr float SqrtE{1.64872}; | |
constexpr float SqrtPhi{1.27202}; | |
constexpr float SqrtPi{1.77245}; | |
double Tan(double x); | |
double Tanh(double x); | |
double Trunc(double x); | |
double Y0(double x); | |
double Y1(double x); | |
double Yn(int n, double x); | |
void init(); | |
} // namespace math | |
static constexpr float angle{0.523599}; | |
static constexpr int cells{100}; | |
std::tuple<double, double> corner(int i, int j); | |
static double cos30; | |
double f(double x, double y); | |
static constexpr int height{320}; | |
void _main(); | |
static double sin30; | |
static constexpr int width{600}; | |
static constexpr float xyrange{30}; | |
static constexpr float xyscale{10}; | |
static constexpr float zscale{128}; | |
int main() { | |
fmt::init(); | |
math::init(); | |
sin30 = math::Sin(angle); | |
cos30 = math::Cos(angle); | |
_main(); | |
return 0; | |
} | |
void _main() { | |
fmt::Printf("<svg xmlns='http://www.w3.org/2000/svg' " + | |
"style='stroke: grey; fill: white; stroke-width: 0.7' " + | |
"width='%d' height='%d'>", | |
width, height); | |
{ | |
int i{0}; | |
for (i = 0; i < cells; i++) { | |
{ | |
int j{0}; | |
for (j = 0; j < cells; j++) { | |
double ax{0}; | |
double ay{0}; | |
double bx{0}; | |
double by{0}; | |
double cx{0}; | |
double cy{0}; | |
double dx{0}; | |
double dy{0}; | |
std::tie(ax, ay) = corner(i + 1, j); | |
std::tie(bx, by) = corner(i, j); | |
std::tie(cx, cy) = corner(i, j + 1); | |
std::tie(dx, dy) = corner(i + 1, j + 1); | |
fmt::Printf("<polygon points='%g,%g %g,%g %g,%g %g,%g'/>\n", ax, ay, | |
bx, by, cx, cy, dx, dy); | |
} | |
} | |
} | |
} | |
fmt::Println("</svg>"); | |
} | |
std::tuple<double, double> corner(int i, int j) { | |
double sx{0}; | |
double sy{0}; | |
double x{0}; | |
double y{0}; | |
double z{0}; | |
x = xyrange * (double(i) / cells - 0.5); | |
y = xyrange * (double(j) / cells - 0.5); | |
z = f(x, y); | |
sx = width / 2 + (x - y) * cos30 * xyscale; | |
sy = height / 2 + (x + y) * sin30 * xyscale - z * zscale; | |
return {sx, sy}; | |
} | |
double f(double x, double y) { | |
double r{0}; | |
r = math::Hypot(x, y); | |
return math::Sin(r) / r; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment