Triangles with fill instead of stroke
This commit is contained in:
parent
4ceb2dbc70
commit
12ef45abfa
1 changed files with 31 additions and 48 deletions
79
main.cpp
79
main.cpp
|
@ -10,6 +10,14 @@ struct pt {
|
|||
ld x = 0, y = 0;
|
||||
};
|
||||
|
||||
bool operator<(pt lhs, pt rhs) {
|
||||
return make_pair(lhs.x, lhs.y) < make_pair(rhs.x, rhs.y);
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& out, pt p) {
|
||||
return out << p.x << ',' << p.y;
|
||||
}
|
||||
|
||||
constexpr pt zero = pt{0, 0};
|
||||
|
||||
pt operator+(pt a, pt b) {
|
||||
|
@ -103,16 +111,11 @@ int main() {
|
|||
pt p31b = unit_triangle(p31a, {0, 0}, c1) * c1;
|
||||
cone c31{p31a, c3, p31b, c1};
|
||||
|
||||
// we keep track of all lines in the construction
|
||||
vector<pair<pt, pt>> rays;
|
||||
rays.emplace_back(zero, c1);
|
||||
rays.emplace_back(zero, c2);
|
||||
rays.emplace_back(zero, c3);
|
||||
|
||||
vector<pair<pt, pt>> lines;
|
||||
lines.emplace_back(p12a, p12b);
|
||||
lines.emplace_back(p23a, p23b);
|
||||
lines.emplace_back(p31a, p31b);
|
||||
// we keep track of all triangles in the construction
|
||||
vector<tuple<pt, pt, pt>> triangles;
|
||||
triangles.emplace_back(p12a, p12b, zero);
|
||||
triangles.emplace_back(p23a, p23b, zero);
|
||||
triangles.emplace_back(p31a, p31b, zero);
|
||||
|
||||
// I use a priority queue to pick the closest cone
|
||||
priority_queue<cone_d> work;
|
||||
|
@ -121,7 +124,7 @@ int main() {
|
|||
work.push(c31);
|
||||
|
||||
// we pick the closest cone to expand
|
||||
while(!work.empty() && lines.size() < 2000) {
|
||||
while(!work.empty() && triangles.size() < 2000) {
|
||||
auto c = work.top().c;
|
||||
work.pop();
|
||||
|
||||
|
@ -139,15 +142,13 @@ int main() {
|
|||
const auto l = sqrt(lensqr(c.p1, c.p2));
|
||||
const auto wiggle = l - 4;
|
||||
const auto r0 = unif01(gen);
|
||||
const auto r = 2.0 / l + pow(r0, 1.5) * wiggle / l;
|
||||
const auto r = 2.0 / l + pow(r0, 1.1) * wiggle / l;
|
||||
const auto pm = (1.0 - r) * c.p1 + r * c.p2;
|
||||
|
||||
const auto r20 = unif01(gen);
|
||||
const auto r2 = 0.001 + 0.998 * pow(r20, 1.2);
|
||||
const auto r2 = 0.001 + 0.998 * pow(r20, 1.1);
|
||||
const auto dm = r2 * c.d1 + (1.0 - r2) * c.d2;
|
||||
|
||||
rays.emplace_back(pm, dm);
|
||||
|
||||
cone c1{c.p1, c.d1, pm, dm};
|
||||
cone c2{pm, dm, c.p2, c.d2};
|
||||
work.push(c1);
|
||||
|
@ -165,49 +166,31 @@ int main() {
|
|||
// the one with a shorter edge, sounds fine to me. I reintroduce
|
||||
// some randomness for artistic reasons. Increase 20 for wild
|
||||
// results.
|
||||
if (lensqr(c.p1, p2b) + 20*unif01(gen) < lensqr(p1b, c.p2) + 20*unif01(gen)) {
|
||||
if (lensqr(c.p1, p2b) + 34*unif01(gen) < lensqr(p1b, c.p2) + 34*unif01(gen)) {
|
||||
cone c2{c.p1, c.d1, p2b, c.d2};
|
||||
work.push(c2);
|
||||
lines.emplace_back(c.p1, p2b);
|
||||
triangles.emplace_back(c.p1, p2b, c.p2);
|
||||
} else {
|
||||
cone c2{p1b, c.d1, c.p2, c.d2};
|
||||
work.push(c2);
|
||||
lines.emplace_back(p1b, c.p2);
|
||||
triangles.emplace_back(c.p1, p1b, c.p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the print an svg attribute
|
||||
const auto p = [](auto str, auto v) {
|
||||
cout << ' ' << str << "=\"" << v << "\"";
|
||||
};
|
||||
|
||||
// I roughly estimate the maximal distance from zero
|
||||
ld max_l = 0;
|
||||
|
||||
shuffle(lines.begin(), lines.end(), gen);
|
||||
|
||||
cout << "<svg>\n";
|
||||
for(auto && l : lines) {
|
||||
max_l = 0.5 * max_l + 0.5 * max(max_l, max(norm(l.first), norm(l.second)));
|
||||
cout << "<line";
|
||||
p("x1", l.first.x);
|
||||
p("y1", l.first.y);
|
||||
p("x2", l.second.x);
|
||||
p("y2", l.second.y);
|
||||
p("style", "stroke:#000;stroke-width:0.1");
|
||||
cout << "/>\n";
|
||||
}
|
||||
for(auto && l : rays) {
|
||||
const auto p1 = l.first;
|
||||
const auto l_left = max(ld(1.0), max_l - norm(p1));
|
||||
const auto p2 = p1 + (l_left / norm(l.second)) * l.second;
|
||||
cout << "<line";
|
||||
p("x1", p1.x);
|
||||
p("y1", p1.y);
|
||||
p("x2", p2.x);
|
||||
p("y2", p2.y);
|
||||
p("style", "stroke:#000;stroke-width:0.1");
|
||||
for(auto && t : triangles) {
|
||||
auto p1 = get<0>(t), p2 = get<1>(t), p3 = get<2>(t);
|
||||
vector<ld> lengths{{norm(p2 - p1), norm(p3 - p2), norm(p1 - p3)}};
|
||||
sort(lengths.begin(), lengths.end());
|
||||
auto r = max(0.0l, min(255.0l, 70 * lengths[2]));
|
||||
auto g = max(0.0l, min(255.0l, 70 * lengths[1]));
|
||||
auto b = max(0.0l, min(255.0l, 256 - 100 * lengths[0]));
|
||||
cout << "<polygon";
|
||||
cout << " points=\"" << get<0>(t) << ' ' << get<1>(t) << ' ' << get<2>(t) << "\"";
|
||||
cout << " style=\"" << "stroke-width:0.01;"
|
||||
<< "fill:rgb(" << r << ", " << g << ", " << b << ");"
|
||||
<< "stroke:rgb(" << max(0.0l, r-100) << ", " << max(0.0l, g-100) << ", " << max(0.0l, b-100) << ");" << "\"";
|
||||
cout << "/>\n";
|
||||
}
|
||||
cout << "</svg>" << endl;
|
||||
|
|
Reference in a new issue