#include <math.h>
class PythagorasTree : public Picture
{
public:
virtual unsigned int getOptions()
{
return FO_ZOOM | FO_FIXRATIO;
}
virtual Rect getDefaultViewport()
{
return Rect::ByCenter(0.0, 4.0, 9.0);
}
static inline Uint32 make_color(int index)
{
index += 17;
return ((index * 23) & 0xFF) << 24
| ((index * 7) & 0xFF) << 16
| ((index * 19) & 0xFF) << 8
| 0x000000FF;
}
int maxdepth;
PythagorasTree() : Picture() {
resetVariables();
}
virtual void resetVariables()
{
maxdepth = 10;
}
int depth;
void drawBase(Canvas &canvas, Point a, Point b)
{
if (depth > maxdepth) return;
depth++;
double len = a.distance(b);
double alpha = atan((b.y-a.y) / (b.x-a.x));
if (a.x > b.x) alpha += M_PI;
Point c ( b.x - len * sin(alpha),
b.y + len * cos(alpha) );
Point d ( a.x - len * sin(alpha),
a.y + len * cos(alpha) );
double mlen = sqrt(len * len / 2);
Point e ( d.x + mlen * cos(alpha + M_PI / 4.0),
d.y + mlen * sin(alpha + M_PI / 4.0) );
canvas.Line(a, b, make_color(depth));
canvas.Line(b, c, make_color(depth));
canvas.Line(c, d, make_color(depth));
canvas.Line(d, a, make_color(depth));
drawBase(canvas, d, e);
drawBase(canvas, e, c);
depth--;
}
virtual void drawPicture(Canvas &c)
{
c.Blank(0x00000000);
depth = 0;
drawBase(c,
Point(-1.0,0.0),
Point(+1.0,0.0));
}
};