summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 332f5d0)
raw | patch | inline | side by side (parent: 332f5d0)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Mon, 19 Jan 2009 08:42:39 +0000 (08:42 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Mon, 19 Jan 2009 08:42:39 +0000 (08:42 +0000) |
src/dyna-draw-context.cpp | patch | blob | history | |
src/dyna-draw-context.h | patch | blob | history |
index bd4f82096765f7dd83e23c4b5750be1e46f2dfb8..8cab1690b5778ff48c3c9be53f4e29b1ebe50478 100644 (file)
ddc->hatch_spacing_step = 0;
new (&ddc->hatch_pointer_past) std::list<double>();
new (&ddc->hatch_nearest_past) std::list<double>();
+ new (&ddc->inertia_vectors) std::list<Geom::Point>();
+ new (&ddc->hatch_vectors) std::list<Geom::Point>();
ddc->hatch_last_nearest = Geom::Point(0,0);
ddc->hatch_last_pointer = Geom::Point(0,0);
- ddc->hatch_vector_accumulated = Geom::Point(0,0);
ddc->hatch_escaped = false;
ddc->hatch_area = NULL;
ddc->hatch_item = NULL;
ddc->hatch_livarot_path = NULL;
ddc->trace_bg = false;
+ ddc->just_started_drawing = false;
}
static void
ddc->hatch_pointer_past.~list();
ddc->hatch_nearest_past.~list();
+ ddc->inertia_vectors.~list();
+ ddc->hatch_vectors.~list();
}
static void
return TRUE;
}
- Geom::Point const button_w(event->button.x,
- event->button.y);
- Geom::Point const button_dt(desktop->w2d(button_w));
- sp_dyna_draw_reset(dc, button_dt);
- sp_dyna_draw_extinput(dc, event);
- sp_dyna_draw_apply(dc, button_dt);
dc->accumulated->reset();
if (dc->repr) {
dc->repr = NULL;
sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 3);
dc->is_drawing = true;
+ dc->just_started_drawing = true;
}
break;
case GDK_MOTION_NOTIFY:
if (event->motion.state & GDK_CONTROL_MASK && dc->hatch_item) { // hatching
+#define HATCH_VECTOR_ELEMENTS 12
+#define INERTIA_ELEMENTS 36
#define SPEED_ELEMENTS 12
-#define SPEED_MIN 0.12
-#define SPEED_NORMAL 0.65
+#define SPEED_MIN 0.3
+#define SPEED_NORMAL 0.3
// speed is the movement of the nearest point along the guide path, divided by
// the movement of the pointer at the same period; it is averaged for the last
// attracted again until the end of this stroke
dc->hatch_escaped = true;
+ if (dc->inertia_vectors.size() >= INERTIA_ELEMENTS/2) { // move by inertia
+ Geom::Point moved_past_escape = motion_dt - dc->inertia_vectors.front();
+ Geom::Point inertia =
+ dc->inertia_vectors.front() - dc->inertia_vectors.back();
+
+ double dot = Geom::dot (moved_past_escape, inertia);
+ dot /= Geom::L2(moved_past_escape) * Geom::L2(inertia);
+
+ if (dot > 0) { // mouse is still moving in approx the same direction
+ Geom::Point should_have_moved =
+ (inertia) * (1/Geom::L2(inertia)) * Geom::L2(moved_past_escape);
+ motion_dt = dc->inertia_vectors.front() + should_have_moved;
+ }
+ }
+
} else {
// Calculate angle cosine of this vector-to-guide and all past vectors
// summed, to detect if we accidentally flipped to the other side of the
// guide
- double dot = Geom::dot (pointer - nearest, dc->hatch_vector_accumulated);
- dot /= Geom::L2(pointer - nearest) * Geom::L2(dc->hatch_vector_accumulated);
+ Geom::Point hatch_vector_accumulated = std::accumulate
+ (dc->hatch_vectors.begin(), dc->hatch_vectors.end(), Geom::Point(0,0));
+ double dot = Geom::dot (pointer - nearest, hatch_vector_accumulated);
+ dot /= Geom::L2(pointer - nearest) * Geom::L2(hatch_vector_accumulated);
if (dc->hatch_spacing != 0) { // spacing was already set
double target;
// return it to the desktop coords
motion_dt = new_pointer * motion_to_curve.inverse();
+ if (speed >= SPEED_NORMAL) {
+ dc->inertia_vectors.push_front(motion_dt);
+ if (dc->inertia_vectors.size() > INERTIA_ELEMENTS)
+ dc->inertia_vectors.pop_back();
+ }
+
} else {
// this is the first motion event, set the dist
dc->hatch_spacing = hatch_dist;
// remember last points
dc->hatch_last_pointer = pointer;
dc->hatch_last_nearest = nearest;
- dc->hatch_vector_accumulated += (pointer - nearest);
+
+ dc->hatch_vectors.push_front(pointer - nearest);
+ if (dc->hatch_vectors.size() > HATCH_VECTOR_ELEMENTS)
+ dc->hatch_vectors.pop_back();
}
dc->_message_context->set(Inkscape::NORMAL_MESSAGE, dc->hatch_escaped? _("Tracking: <b>connection to guide path lost!</b>") : _("<b>Tracking</b> a guide path"));
dc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Drawing</b> a calligraphic stroke"));
}
+ if (dc->just_started_drawing) {
+ dc->just_started_drawing = false;
+ sp_dyna_draw_reset(dc, motion_dt);
+ }
+
if (!sp_dyna_draw_apply(dc, motion_dt)) {
ret = TRUE;
break;
sp_canvas_item_show(dc->hatch_area);
} else if (dc->dragging && dc->hatch_escaped) {
// Tracking escaped: red, center free, fixed radius
- Geom::Point c = desktop->w2d(motion_w);
+ Geom::Point c = motion_dt;
Geom::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
sp_canvas_item_affine_absolute(dc->hatch_area, sm);
if (!dc->hatch_pointer_past.empty()) dc->hatch_pointer_past.clear();
if (!dc->hatch_nearest_past.empty()) dc->hatch_nearest_past.clear();
+ if (!dc->inertia_vectors.empty()) dc->inertia_vectors.clear();
+ if (!dc->hatch_vectors.empty()) dc->hatch_vectors.clear();
dc->hatch_last_nearest = Geom::Point(0,0);
dc->hatch_last_pointer = Geom::Point(0,0);
- dc->hatch_vector_accumulated = Geom::Point(0,0);
dc->hatch_escaped = false;
dc->hatch_item = NULL;
dc->hatch_livarot_path = NULL;
+ dc->just_started_drawing = false;
if (dc->hatch_spacing != 0 && !dc->keep_selected) {
// we do not select the newly drawn path, so increase spacing by step
index ddab2b53cf4128c062d0123889e1ecbe60a42bba..19cbfbb29f2f2cdec57ade900685df0ca85c1303 100644 (file)
--- a/src/dyna-draw-context.h
+++ b/src/dyna-draw-context.h
Path *hatch_livarot_path;
std::list<double> hatch_nearest_past;
std::list<double> hatch_pointer_past;
+ std::list<Geom::Point> inertia_vectors;
Geom::Point hatch_last_nearest, hatch_last_pointer;
- Geom::Point hatch_vector_accumulated;
+ std::list<Geom::Point> hatch_vectors;
bool hatch_escaped;
SPCanvasItem *hatch_area;
-
+ bool just_started_drawing;
bool trace_bg;
};