/* Returns a spline describing one edge of a puzzle piece of the given length. */ static spline * make_puzzle_curve (int pixels) { double x0 = 0.0000, y0 = 0.0000; double x1 = 0.3333, y1 = 0.1000; double x2 = 0.4333, y2 = 0.0333; double x3 = 0.4666, y3 = -0.0666; double x4 = 0.3333, y4 = -0.1666; double x5 = 0.3666, y5 = -0.2900; double x6 = 0.5000, y6 = -0.3333; spline *s = make_spline(20); s->n_controls = 0; # define PT(x,y) \ s->control_x[s->n_controls] = pixels * (x); \ s->control_y[s->n_controls] = pixels * (y); \ s->n_controls++ PT ( x0, y0); PT ( x1, y1); PT ( x2, y2); PT ( x3, y3); PT ( x4, y4); PT ( x5, y5); PT ( x6, y6); PT (1-x5, y5); PT (1-x4, y4); PT (1-x3, y3); PT (1-x2, y2); PT (1-x1, y1); PT (1-x0, y0); # undef PT compute_spline (s); return s; }
static Bool make_blob(blob * b, int maxx, int maxy, int size) { int i; long mid; maxx *= SCALE; maxy *= SCALE; size *= SCALE; b->max_r = size / 2; b->min_r = size / 10; if (b->min_r < (5 * SCALE)) b->min_r = (5 * SCALE); mid = ((b->min_r + b->max_r) / 2); b->torque = 0.0075; /* torque init */ b->elasticity = (long) (SCALE * 1.8); /* elasticity init */ b->max_velocity = (long) (SCALE * 1.2); /* max_velocity init */ b->x = NRAND(maxx); b->y = NRAND(maxy); b->dx = NRAND(b->max_velocity) * RANDSIGN(); b->dy = NRAND(b->max_velocity) * RANDSIGN(); b->th = (2.0 * M_PI) * LRAND() / MAXRAND * RANDSIGN(); b->npoints = (int) (LRAND() % 5) + 5; b->splines = make_spline(b->npoints); if ((b->r = (long *) malloc(sizeof (*b->r) * b->npoints)) == NULL) return False; for (i = 0; i < b->npoints; i++) b->r[i] = ((LRAND() % mid) + (mid / 2)) * RANDSIGN(); return True; }
static struct starfish * make_starfish (struct state *st, int maxx, int maxy, int size) { struct starfish *s = (struct starfish *) calloc(1, sizeof(*s)); int i; s->blob_p = st->blob_p; s->elasticity = SCALE * get_float_resource (st->dpy, "thickness", "Thickness"); if (s->elasticity == 0) /* bell curve from 0-15, avg 7.5 */ s->elasticity = RAND(5*SCALE) + RAND(5*SCALE) + RAND(5*SCALE); s->rotv = get_float_resource (st->dpy, "rotation", "Rotation"); if (s->rotv == -1) /* bell curve from 0-12 degrees, avg 6 */ s->rotv = frand(4) + frand(4) + frand(4); s->rotv /= 360; /* convert degrees to ratio */ if (s->blob_p) { s->elasticity *= 3; s->rotv *= 3; } s->rot_max = s->rotv * 2; s->rota = 0.0004 + frand(0.0002); if (! (random() % 20)) size *= frand(0.35) + frand(0.35) + 0.3; { static const char skips[] = { 2, 2, 2, 2, 3, 3, 3, 6, 6, 12 }; s->skip = skips[random() % sizeof(skips)]; } if (! (random() % (s->skip == 2 ? 3 : 12))) s->mode = zoom; else s->mode = pulse; maxx *= SCALE; maxy *= SCALE; size *= SCALE; s->max_r = size; s->min_r = 0; if (s->min_r < (5*SCALE)) s->min_r = (5*SCALE); s->x = maxx/2; s->y = maxy/2; s->th = frand(M_PI+M_PI) * RANDSIGN(); { static const char sizes[] = { 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 8, 8, 8, 10, 35 }; int nsizes = sizeof(sizes); if (s->skip > 3) nsizes -= 4; s->npoints = s->skip * sizes[random() % nsizes]; } s->spline = make_spline (s->npoints); s->r = (long *) malloc (sizeof(*s->r) * s->npoints); for (i = 0; i < s->npoints; i++) s->r[i] = ((i % s->skip) == 0) ? 0 : size; return s; }
surface::instance_t make(const description_t& description) { BOOST_LOG_TRIVIAL(debug) << "Make surface sor"; const auto& points = description.points; spline_t spline = make_spline(points.begin(), points.end()); derivations_t derivations; rtree_t rtree; for (std::size_t i = 0; i < spline.size(); ++i) { const spline_segment_t& segment = spline[i]; const polynomial5_t derivation = differentiate(std::get<2>(segment) * std::get<2>(segment)); const float delta = std::get<1>(segment) - std::get<0>(segment); float max = std::max ( evaluate(std::get<2>(segment), 0.0f), evaluate(std::get<2>(segment), delta) ); std::array<float, 5> roots; const auto end = solve(derivation, roots.begin()); for (auto root = roots.begin(); root != end; ++root) if (*root >= 0.0f && *root <= delta) max = std::max ({ max, evaluate(std::get<2>(segment), *root) }); const box_t box ( point_t(-max, std::get<0>(segment), -max), point_t(+max, std::get<1>(segment), +max) ); derivations.emplace_back(derivation); rtree.insert(value_t(box, i)); } /* const box_t box = transform ( description.transformation, box_t// TODO: puke => ( vector_t { geo::get<X>(rtree.bounds().min_corner()), geo::get<Y>(rtree.bounds().min_corner()), geo::get<Z>(rtree.bounds().min_corner()) }, vector_t { geo::get<X>(rtree.bounds().max_corner()), geo::get<Y>(rtree.bounds().max_corner()), geo::get<Z>(rtree.bounds().max_corner()) } ) ); BOOST_LOG_TRIVIAL(trace) << "Box: min = " << box.min_corner() << ", max = " << box.max_corner() << std::endl; const box_t box// TODO: puke => ( vector_t { geo::get<X>(rtree.bounds().min_corner()), geo::get<Y>(rtree.bounds().min_corner()), geo::get<Z>(rtree.bounds().min_corner()) }, vector_t { geo::get<X>(rtree.bounds().max_corner()), geo::get<Y>(rtree.bounds().max_corner()), geo::get<Z>(rtree.bounds().max_corner()) } ); BOOST_LOG_TRIVIAL(trace) << "Box: min = " << box.min_corner() << ", max = " << box.max_corner() << std::endl; */ model_t model ( std::move(spline), std::move(derivations), std::move(rtree), points.front()[X], points.back()[X], points.front()[Y], points.back()[Y] // box ); return std::make_shared<instance_impl_t<model_t>>(description.transformation, std::move(model)); // return boost::make_tuple // ( // primitive::make<model> // ( // description.transformation, // std::move(spline), // std::move(derivations), // std::move(rtree), // points.front()[X], // points.back()[X], // points.front()[Y], // points.back()[Y] // ), // box, // 3 * spline.size() + 2 // ); }