|
|
2a4477 |
|
|
|
2a4477 |
#include "generatorsandboxview.h"
|
|
|
2a4477 |
|
|
|
2a4477 |
|
|
|
2a4477 |
GeneratorSandBoxView::GenPoint::GenPoint(const IntVector2 &coord):
|
|
|
2a4477 |
coord(coord)
|
|
|
2a4477 |
{
|
|
|
2a4477 |
UInt x = UInt(coord.x);
|
|
|
2a4477 |
UInt y = UInt(coord.y);
|
|
|
2a4477 |
UInt step_x = coord.x ? (x^(x - 1)) >> 1 : UInt(-1);
|
|
|
2a4477 |
UInt step_y = coord.y ? (y^(y - 1)) >> 1 : UInt(-1);
|
|
|
2a4477 |
|
|
|
2a4477 |
UInt step_xy = (step_x < step_y ? step_x : step_y) + 1;
|
|
|
2a4477 |
diamond = step_x != step_y;
|
|
|
2a4477 |
|
|
|
2a4477 |
if (!step_xy || step_xy > one) step_xy = one;
|
|
|
2a4477 |
step = Int(step_xy);
|
|
|
2a4477 |
|
|
|
2a4477 |
level = -1;
|
|
|
2a4477 |
for(int l = 0; l <= max_level; ++l)
|
|
|
2a4477 |
if (step == (1 << (max_level - l)))
|
|
|
2a4477 |
level = l;
|
|
|
2a4477 |
assert(level >= 0);
|
|
|
2a4477 |
}
|
|
|
2a4477 |
|
|
|
2a4477 |
void
|
|
|
2a4477 |
GeneratorSandBoxView::GenPoint::get_parents(Set &out_points) const
|
|
|
2a4477 |
{
|
|
|
2a4477 |
if (!level || out_points.count(*this)) return;
|
|
|
2a4477 |
|
|
|
2a4477 |
GenPoint points[4];
|
|
|
2a4477 |
if (diamond) {
|
|
|
2a4477 |
points[0] = GenPoint(coord.x - step, coord.y);
|
|
|
2a4477 |
points[1] = GenPoint(coord.x + step, coord.y);
|
|
|
2a4477 |
points[2] = GenPoint(coord.x, coord.y - step);
|
|
|
2a4477 |
points[3] = GenPoint(coord.x, coord.y + step);
|
|
|
2a4477 |
} else {
|
|
|
2a4477 |
points[0] = GenPoint(coord.x - step, coord.y - step);
|
|
|
2a4477 |
points[1] = GenPoint(coord.x - step, coord.y + step);
|
|
|
2a4477 |
points[2] = GenPoint(coord.x + step, coord.y - step);
|
|
|
2a4477 |
points[3] = GenPoint(coord.x + step, coord.y + step);
|
|
|
2a4477 |
}
|
|
|
2a4477 |
for(int i = 0; i < 4; ++i) {
|
|
|
2a4477 |
points[i].get_parents(out_points);
|
|
|
2a4477 |
out_points.insert(points[i]);
|
|
|
2a4477 |
}
|
|
|
2a4477 |
}
|
|
|
2a4477 |
|
|
|
2a4477 |
void
|
|
|
2a4477 |
GeneratorSandBoxView::GenPoint::draw(const Cairo::RefPtr<cairo::context> &context) const {</cairo::context>
|
|
|
2a4477 |
Real fstep = 1/Real(one);
|
|
|
2a4477 |
Real fsize = pow(Real(0.9), Real(level)) * fstep;
|
|
|
2a4477 |
|
|
|
2a4477 |
Vector2 fcoord(coord.x*fstep, coord.y*fstep);
|
|
|
2a4477 |
|
|
|
2a4477 |
if (!level) {
|
|
|
2a4477 |
Real s = fsize/sqrt(M_PI);
|
|
|
2a4477 |
context->arc(fcoord.x, fcoord.y, s, 0, 2*M_PI);
|
|
|
2a4477 |
} else
|
|
|
2a4477 |
if (diamond) {
|
|
|
2a4477 |
Real s = fsize*sqrt(0.5);
|
|
|
2a4477 |
context->move_to(fcoord.x - s, fcoord.y);
|
|
|
2a4477 |
context->line_to(fcoord.x, fcoord.y - s);
|
|
|
2a4477 |
context->line_to(fcoord.x + s, fcoord.y);
|
|
|
2a4477 |
context->line_to(fcoord.x, fcoord.y + s);
|
|
|
2a4477 |
context->close_path();
|
|
|
2a4477 |
} else {
|
|
|
2a4477 |
Real s = fsize*0.5;
|
|
|
2a4477 |
context->move_to(fcoord.x - s, fcoord.y - s);
|
|
|
2a4477 |
context->line_to(fcoord.x - s, fcoord.y + s);
|
|
|
2a4477 |
context->line_to(fcoord.x + s, fcoord.y + s);
|
|
|
2a4477 |
context->line_to(fcoord.x + s, fcoord.y - s);
|
|
|
2a4477 |
context->close_path();
|
|
|
2a4477 |
}
|
|
|
2a4477 |
context->fill();
|
|
|
2a4477 |
}
|
|
|
2a4477 |
|
|
|
2a4477 |
|
|
|
2a4477 |
|
|
|
2a4477 |
GeneratorSandBoxView::GeneratorSandBoxView():
|
|
|
2a4477 |
p0(new View::Point( Vector2(-0.25, -0.25) )),
|
|
|
2a4477 |
p1(new View::Point( Vector2( 0.25, 0.25) ))
|
|
|
2a4477 |
{
|
|
|
2a4477 |
transform.scale(200, 200);
|
|
|
2a4477 |
points.push_back(p0);
|
|
|
2a4477 |
points.push_back(p1);
|
|
|
2a4477 |
}
|
|
|
2a4477 |
|
|
|
2a4477 |
void
|
|
|
2a4477 |
GeneratorSandBoxView::on_draw_view(const Cairo::RefPtr<cairo::context> &context) {</cairo::context>
|
|
|
2a4477 |
context->save();
|
|
|
2a4477 |
|
|
|
2a4477 |
const Real ps = get_pixel_size();
|
|
|
2a4477 |
context->set_line_width(ps);
|
|
|
2a4477 |
|
|
|
2a4477 |
Pair2 bounds(p0->position, p1->position);
|
|
|
2a4477 |
|
|
|
2a4477 |
// calc view bounds
|
|
|
2a4477 |
int w = get_allocated_width();
|
|
|
2a4477 |
int h = get_allocated_height();
|
|
|
2a4477 |
Matrix m = transform_from_pixels();
|
|
|
2a4477 |
Pair2 view_bounds(Vector2(INFINITY, INFINITY), Vector2(-INFINITY, -INFINITY));
|
|
|
2a4477 |
view_bounds.expand((m*Vector4(0, 0, 0, 1)).vec2());
|
|
|
2a4477 |
view_bounds.expand((m*Vector4(w, 0, 0, 1)).vec2());
|
|
|
2a4477 |
view_bounds.expand((m*Vector4(0, h, 0, 1)).vec2());
|
|
|
2a4477 |
view_bounds.expand((m*Vector4(w, h, 0, 1)).vec2());
|
|
|
2a4477 |
|
|
|
2a4477 |
// calc int bounds
|
|
|
2a4477 |
Real fstep = 1/Real(GenPoint::one);
|
|
|
2a4477 |
IntPair2 bounds_int(
|
|
|
2a4477 |
IntVector2( Int(ceil (bounds.p0.x/fstep - real_precision)),
|
|
|
2a4477 |
Int(ceil (bounds.p0.y/fstep - real_precision)) ),
|
|
|
2a4477 |
IntVector2( Int(floor(bounds.p1.x/fstep + real_precision)),
|
|
|
2a4477 |
Int(floor(bounds.p1.y/fstep + real_precision)) ));
|
|
|
2a4477 |
IntPair2 view_bounds_int(
|
|
|
2a4477 |
IntVector2( Int(floor(view_bounds.p0.x/fstep - 2 + real_precision)),
|
|
|
2a4477 |
Int(floor(view_bounds.p0.y/fstep - 2 + real_precision)) ),
|
|
|
2a4477 |
IntVector2( Int(ceil (view_bounds.p1.x/fstep + 2 - real_precision)),
|
|
|
2a4477 |
Int(ceil (view_bounds.p1.y/fstep + 2 - real_precision)) ));
|
|
|
2a4477 |
|
|
|
2a4477 |
// draw background points
|
|
|
2a4477 |
context->set_source_rgba(0.5, 0.5, 0.5, 0.75);
|
|
|
2a4477 |
for(Int x = view_bounds_int.p0.x; x <= view_bounds_int.p1.x; ++x)
|
|
|
2a4477 |
for(Int y = view_bounds_int.p0.y; y <= view_bounds_int.p1.y; ++y)
|
|
|
2a4477 |
GenPoint(x, y).draw(context);
|
|
|
2a4477 |
|
|
|
2a4477 |
// ganer parent points
|
|
|
2a4477 |
GenPoint::Set parents;
|
|
|
2a4477 |
for(Int x = bounds_int.p0.x; x <= bounds_int.p1.x; ++x)
|
|
|
2a4477 |
for(Int y = bounds_int.p0.y; y <= bounds_int.p1.y; ++y)
|
|
|
2a4477 |
GenPoint(x, y).get_parents(parents);
|
|
|
2a4477 |
context->set_source_rgba(1, 0, 0, 1);
|
|
|
2a4477 |
for(GenPoint::Set::const_iterator i = parents.begin(); i != parents.end(); ++i)
|
|
|
2a4477 |
i->draw(context);
|
|
|
2a4477 |
|
|
|
2a4477 |
// draw selected points
|
|
|
2a4477 |
context->set_source_rgba(0, 0, 1, 0.55);
|
|
|
2a4477 |
for(Int x = bounds_int.p0.x; x <= bounds_int.p1.x; ++x)
|
|
|
2a4477 |
for(Int y = bounds_int.p0.y; y <= bounds_int.p1.y; ++y)
|
|
|
2a4477 |
GenPoint(x, y).draw(context);
|
|
|
2a4477 |
|
|
|
2a4477 |
// draw bounds
|
|
|
2a4477 |
context->set_source_rgba(0, 0, 1, 0.75);
|
|
|
2a4477 |
context->move_to(bounds.p0.x, bounds.p0.y);
|
|
|
2a4477 |
context->line_to(bounds.p1.x, bounds.p0.y);
|
|
|
2a4477 |
context->line_to(bounds.p1.x, bounds.p1.y);
|
|
|
2a4477 |
context->line_to(bounds.p0.x, bounds.p1.y);
|
|
|
2a4477 |
context->close_path();
|
|
|
2a4477 |
context->stroke();
|
|
|
2a4477 |
|
|
|
2a4477 |
context->restore();
|
|
|
2a4477 |
}
|
|
|
2a4477 |
|