|
|
a7e4c0 |
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
#include "random.h"
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
#include "curvearea.h"
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
CurveArea::CurveArea():
|
|
|
a7e4c0 |
hp0(new ActivePoint(Vector(100, 120), Color::white())),
|
|
|
a7e4c0 |
hp1(new ActivePoint(Vector(400, 420), Color::white())),
|
|
|
a7e4c0 |
ht0(new ActivePoint(Vector(400, 120), Color::yellow())),
|
|
|
a7e4c0 |
ht1(new ActivePoint(Vector(800, 420), Color::yellow())),
|
|
|
a7e4c0 |
bp0(new ActivePoint(Vector(600, 80), Color::white())),
|
|
|
a7e4c0 |
bp1(new ActivePoint(Vector(900, 380), Color::white())),
|
|
|
a7e4c0 |
bpp0(new ActivePoint(Vector(700, 80), Color::yellow())),
|
|
|
a7e4c0 |
bpp1(new ActivePoint(Vector(800, 380), Color::yellow())),
|
|
|
a7e4c0 |
cross(new ActivePoint(Vector(500, 250), Color::gray()))
|
|
|
a7e4c0 |
{
|
|
|
a7e4c0 |
set_size_request(1000, 500);
|
|
|
a7e4c0 |
add_point(hp0);
|
|
|
a7e4c0 |
add_point(hp1);
|
|
|
a7e4c0 |
add_point(ht0);
|
|
|
a7e4c0 |
add_point(ht1);
|
|
|
a7e4c0 |
add_point(bp0);
|
|
|
a7e4c0 |
add_point(bp1);
|
|
|
a7e4c0 |
add_point(bpp0);
|
|
|
a7e4c0 |
add_point(bpp1);
|
|
|
a7e4c0 |
add_point(cross);
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::on_point_move(const ActivePoint::Handle &point, const Vector &oldposition, const Vector &newposition) {
|
|
|
a7e4c0 |
if (point == hp0)
|
|
|
a7e4c0 |
ht0->position += newposition - oldposition;
|
|
|
a7e4c0 |
if (point == hp1)
|
|
|
a7e4c0 |
ht1->position += newposition - oldposition;
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::put_rect(const Context &context, const Rect &rect) {
|
|
|
a7e4c0 |
context->move_to(rect.x0, rect.y0);
|
|
|
a7e4c0 |
context->line_to(rect.x1, rect.y0);
|
|
|
a7e4c0 |
context->line_to(rect.x1, rect.y1);
|
|
|
a7e4c0 |
context->line_to(rect.x0, rect.y1);
|
|
|
a7e4c0 |
context->close_path();
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::put_hmark(const Context &context, const Vector &point) {
|
|
|
a7e4c0 |
context->move_to(point.x, point.y - 10);
|
|
|
a7e4c0 |
context->line_to(point.x, point.y + 10);
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::put_vmark(const Context &context, const Vector &point) {
|
|
|
a7e4c0 |
context->move_to(point.x - 10, point.y);
|
|
|
a7e4c0 |
context->line_to(point.x + 10, point.y);
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::put_hline(const Context &context, const Vector &point) {
|
|
|
a7e4c0 |
Real width = get_allocated_width();
|
|
|
a7e4c0 |
context->move_to(0, point.y);
|
|
|
a7e4c0 |
context->line_to(width, point.y);
|
|
|
a7e4c0 |
put_vmark(context, point);
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::put_vline(const Context &context, const Vector &point) {
|
|
|
a7e4c0 |
Real height = get_allocated_height();
|
|
|
a7e4c0 |
context->move_to(point.x, 0);
|
|
|
a7e4c0 |
context->line_to(point.x, height);
|
|
|
a7e4c0 |
put_hmark(context, point);
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::put_cross(const Context &context, const Vector &point) {
|
|
|
a7e4c0 |
put_hmark(context, point);
|
|
|
a7e4c0 |
put_vmark(context, point);
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
void CurveArea::on_draw_content(const Context &context) {
|
|
|
a7e4c0 |
Real roots[3];
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context->save();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_line_width_px(1);
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray().mulalpha(0.5));
|
|
|
a7e4c0 |
put_vline(context, cross->position);
|
|
|
a7e4c0 |
put_hline(context, cross->position);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
{
|
|
|
a7e4c0 |
context.set_line_width_px(1);
|
|
|
a7e4c0 |
Hermite h(
|
|
|
a7e4c0 |
hp0->position,
|
|
|
a7e4c0 |
hp1->position,
|
|
|
a7e4c0 |
ht0->position - hp0->position,
|
|
|
a7e4c0 |
ht1->position - hp1->position );
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray());
|
|
|
a7e4c0 |
context.move_to(hp0->position);
|
|
|
a7e4c0 |
context.line_to(ht0->position);
|
|
|
a7e4c0 |
context.move_to(hp1->position);
|
|
|
a7e4c0 |
context.line_to(ht1->position);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray().mulalpha(0.25));
|
|
|
a7e4c0 |
put_rect(context, h.bounds_accurate());
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray().mulalpha(0.5));
|
|
|
a7e4c0 |
for(int i = h.bends_x(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, h(roots[i]));
|
|
|
a7e4c0 |
for(int i = h.bends_y(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, h(roots[i]));
|
|
|
a7e4c0 |
for(int i = h.intersections_x(roots, cross->position.x) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_vmark(context, h(roots[i]));
|
|
|
a7e4c0 |
for(int i = h.intersections_y(roots, cross->position.y) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_hmark(context, h(roots[i]));
|
|
|
a7e4c0 |
for(int i = h.inflection_x(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, h(roots[i]));
|
|
|
a7e4c0 |
for(int i = h.inflection_y(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, h(roots[i]));
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::blue().withalpha(0.5));
|
|
|
a7e4c0 |
context.hermite(h);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_line_width_px(3);
|
|
|
a7e4c0 |
Bezier bb = h.sub(rnd::real(), rnd::real()).get_bezier();
|
|
|
a7e4c0 |
context.set_source_rgba(Color::blue());
|
|
|
a7e4c0 |
context.bezier(bb);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
{
|
|
|
a7e4c0 |
context.set_line_width_px(1);
|
|
|
a7e4c0 |
Bezier b(
|
|
|
a7e4c0 |
bp0->position,
|
|
|
a7e4c0 |
bp1->position,
|
|
|
a7e4c0 |
bpp0->position,
|
|
|
a7e4c0 |
bpp1->position );
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray());
|
|
|
a7e4c0 |
context.move_to(bp0->position);
|
|
|
a7e4c0 |
context.line_to(bpp0->position);
|
|
|
a7e4c0 |
context.line_to(bpp1->position);
|
|
|
a7e4c0 |
context.line_to(bp1->position);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray().mulalpha(0.25));
|
|
|
a7e4c0 |
put_rect(context, b.bounds_accurate());
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::gray().mulalpha(0.5));
|
|
|
a7e4c0 |
for(int i = b.bends_x(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, b(roots[i]));
|
|
|
a7e4c0 |
for(int i = b.bends_y(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, b(roots[i]));
|
|
|
a7e4c0 |
for(int i = b.intersections_x(roots, cross->position.x) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_vmark(context, b(roots[i]));
|
|
|
a7e4c0 |
for(int i = b.intersections_y(roots, cross->position.y) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_hmark(context, b(roots[i]));
|
|
|
a7e4c0 |
for(int i = b.inflection_x(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, b(roots[i]));
|
|
|
a7e4c0 |
for(int i = b.inflection_y(roots) - 1; i >= 0; --i)
|
|
|
a7e4c0 |
put_cross(context, b(roots[i]));
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_source_rgba(Color::blue().mulalpha(0.5));
|
|
|
a7e4c0 |
context.bezier(b);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context.set_line_width_px(3);
|
|
|
a7e4c0 |
Hermite hh = b.sub(rnd::real(), rnd::real()).get_hermite();
|
|
|
a7e4c0 |
context.set_source_rgba(Color::blue());
|
|
|
a7e4c0 |
context.hermite(hh);
|
|
|
a7e4c0 |
context->stroke();
|
|
|
a7e4c0 |
}
|
|
|
a7e4c0 |
|
|
|
a7e4c0 |
context->restore();
|
|
|
a7e4c0 |
}
|