diff --git a/main.cpp b/main.cpp index 3a6958b..661c171 100644 --- a/main.cpp +++ b/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> rays; - rays.emplace_back(zero, c1); - rays.emplace_back(zero, c2); - rays.emplace_back(zero, c3); - - vector> 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> 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 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 << "\n"; - for(auto && l : lines) { - max_l = 0.5 * max_l + 0.5 * max(max_l, max(norm(l.first), norm(l.second))); - 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 << "(t), p2 = get<1>(t), p3 = get<2>(t); + vector 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 << "(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 << "" << endl;