Sierpinski curve: Difference between revisions

Content added Content deleted
(Added AutoHotkey)
m (Refactored C++ code)
Line 173: Line 173:
#include <string>
#include <string>


class sierpinski_curve {
std::string rewrite(const std::string& s) {
public:
void write(std::ostream& out, int size, double x, double y,
int length, int order);
private:
static std::string rewrite(const std::string& s);
void line(std::ostream& out);
void execute(std::ostream& out, const std::string& s);
double x_;
double y_;
int angle_;
int length_;
};

void sierpinski_curve::write(std::ostream& out, int size, double x, double y,
int length, int order) {
length_ = length;
x_ = x;
y_ = y;
angle_ = 45;
out << "<svg xmlns='http://www.w3.org/2000/svg' width='"
<< size << "' height='" << size << "'>\n";
out << "<rect width='100%' height='100%' fill='white'/>\n";
out << "<path stroke-width='1' stroke='black' fill='none' d='";
std::string s = "F--XF--F--XF";
for (int i = 0; i < order; ++i)
s = rewrite(s);
execute(out, s);
out << "'/>\n</svg>\n";
}

std::string sierpinski_curve::rewrite(const std::string& s) {
std::string t;
std::string t;
for (char c : s) {
for (char c : s) {
Line 184: Line 215:
}
}


void line(std::ostream& out, double& x, double& y, double length, int angle) {
void sierpinski_curve::line(std::ostream& out) {
constexpr double pi = 3.14159265359;
double theta = (3.14159265359 * angle_)/180.0;
double theta = (pi * angle)/180.0;
x_ += length_ * std::cos(theta);
x += length * std::cos(theta);
y_ -= length_ * std::sin(theta);
y -= length * std::sin(theta);
out << " L" << x_ << ',' << y_;
out << 'L' << x << ',' << y << '\n';
}
}


void execute(std::ostream& out, const std::string& s, double x, double y,
void sierpinski_curve::execute(std::ostream& out, const std::string& s) {
double length, int angle) {
out << 'M' << x_ << ',' << y_;
out << 'M' << x << ',' << y << '\n';
for (char c : s) {
for (char c : s) {
if (c == 'F' || c == 'G')
switch (c) {
case 'F':
line(out, x, y, length, angle);
else if (c == '+')
case 'G':
angle = (angle + 45) % 360;
line(out);
else if (c == '-')
break;
angle = (angle - 45) % 360;
case '+':
angle_ = (angle_ + 45) % 360;
break;
case '-':
angle_ = (angle_ - 45) % 360;
break;
}
}
}
}
}


int main() {
int main() {
const int size = 545;
const int order = 5;
const double x = 5, y = 10, length = 7;
std::ofstream out("sierpinski_curve.svg");
std::ofstream out("sierpinski_curve.svg");
if (!out) {
if (!out) {
Line 214: Line 246:
return 1;
return 1;
}
}
sierpinski_curve s;
out << "<svg xmlns='http://www.w3.org/2000/svg' width='"
s.write(out, 545, 5, 10, 7, 5);
<< size << "' height='" << size << "'>\n";
out << "<rect width='100%' height='100%' fill='white'/>\n";
out << "<path stroke-width='1' stroke='black' fill='none' d='";
std::string s = "F--XF--F--XF";
for (int i = 0; i < order; ++i)
s = rewrite(s);
execute(out, s, x, y, length, 45);
out << "'/>\n</svg>\n";
return 0;
return 0;
}</lang>
}</lang>


{{out}}
{{out}}
See: [https://slack-files.com/T0CNUL56D-F017EPDTKS4-6d6b01b464 sierpinski_curve.svg] (offsite SVG image)
See: [https://slack-files.com/T0CNUL56D-F01GBK1GF2B-6c7c86c4e7 sierpinski_curve.svg] (offsite SVG image)


=={{header|Factor}}==
=={{header|Factor}}==