diff options
| author | Diederik van Lierop <mail@diedenrezi.nl> | 2007-12-08 21:18:49 +0000 |
|---|---|---|
| committer | dvlierop2 <dvlierop2@users.sourceforge.net> | 2007-12-08 21:18:49 +0000 |
| commit | 60310d81f6d2ab4b7e919a07097e95d187c3273f (patch) | |
| tree | 0e907f212c69edb1674514bb28555dacd5fb746b /src/display | |
| parent | corrected a typo and added a check for modevia name definition. fall back on ... (diff) | |
| download | inkscape-60310d81f6d2ab4b7e919a07097e95d187c3273f.tar.gz inkscape-60310d81f6d2ab4b7e919a07097e95d187c3273f.zip | |
Snap to axonometric grid lines
(bzr r4194)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/canvas-axonomgrid.cpp | 76 | ||||
| -rw-r--r-- | src/display/canvas-grid.cpp | 9 |
2 files changed, 72 insertions, 13 deletions
diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index a74151523..e16e1fdf2 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -22,10 +22,10 @@ #include "sp-canvas-util.h" #include "canvas-axonomgrid.h" #include "util/mathfns.h" +#include "2geom/geom.h" #include "display-forward.h" #include <libnr/nr-pixops.h> - #include "canvas-grid.h" #include "desktop-handles.h" #include "helper/units.h" @@ -619,20 +619,74 @@ CanvasAxonomGridSnapper::_getSnapLines(NR::Point const &p) const } /* This is to make sure we snap to only visible grid lines */ - double scaled_spacing = grid->spacing_ylines; // this is spacing of visible lines if screen pixels + double scaled_spacing_h = grid->spacing_ylines; // this is spacing of visible lines if screen pixels + double scaled_spacing_v = grid->lyw; // vertical // convert screen pixels to px // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary if (SP_ACTIVE_DESKTOP) { - scaled_spacing /= SP_ACTIVE_DESKTOP->current_zoom(); - } - - NR::Coord rounded; - rounded = Inkscape::Util::round_to_nearest_multiple_plus(p[0], scaled_spacing, grid->origin[0]); - s.push_back(std::make_pair(NR::Dim2(0), rounded)); - rounded = Inkscape::Util::round_to_lower_multiple_plus(p[0], scaled_spacing, grid->origin[0]); - s.push_back(std::make_pair(NR::Dim2(0), rounded)); - + scaled_spacing_h /= SP_ACTIVE_DESKTOP->current_zoom(); + scaled_spacing_v /= SP_ACTIVE_DESKTOP->current_zoom(); + } + + // In an axonometric grid, any point will be surrounded by 6 grid lines: + // - 2 vertical grid lines, one left and one right from the point + // - 2 angled z grid lines, one above and one below the point + // - 2 angled x grid lines, one above and one below the point + + // Calculate the x coordinate of the vertical grid lines + NR::Coord x_max = Inkscape::Util::round_to_upper_multiple_plus(p[NR::X], scaled_spacing_h, grid->origin[NR::X]); + NR::Coord x_min = Inkscape::Util::round_to_lower_multiple_plus(p[NR::X], scaled_spacing_h, grid->origin[NR::X]); + + // Calculate the y coordinate of the intersection of the angled grid lines with the y-axis + double y_proj_along_z = p[NR::Y] - grid->tan_angle[Z]*(p[NR::X] - grid->origin[NR::X]); + double y_proj_along_x = p[NR::Y] + grid->tan_angle[X]*(p[NR::X] - grid->origin[NR::X]); + double y_proj_along_z_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_z, scaled_spacing_v, grid->origin[NR::Y]); + double y_proj_along_z_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_z, scaled_spacing_v, grid->origin[NR::Y]); + double y_proj_along_x_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[NR::Y]); + double y_proj_along_x_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[NR::Y]); + + // Calculate the normal for the angled grid lines + NR::Point norm_x = NR::rot90(NR::Point(1, -grid->tan_angle[X])); + NR::Point norm_z = NR::rot90(NR::Point(1, grid->tan_angle[Z])); + + // The four angled grid lines form a parallellogram, enclosing the point + // One of the two vertical grid lines divides this parallellogram in two triangles + // We will now try to find out in which half (i.e. triangle) our point is, and return + // only the three grid lines defining that triangle + + // The vertical grid line is at the intersection of two angled grid lines. + // Now go find that intersection! + Geom::Point result; + Geom::IntersectorKind is = line_intersection(norm_x.to_2geom(), norm_x[NR::Y]*y_proj_along_x_max, + norm_z.to_2geom(), norm_z[NR::Y]*y_proj_along_z_max, + result); + + // Determine which half of the parallellogram to use + bool use_left_half = true; + bool use_right_half = true; + + if (is == Geom::intersects) { + use_left_half = (p[NR::X] - grid->origin[NR::X]) < result[Geom::X]; + use_right_half = !use_left_half; + } + + //std::cout << "intersection at " << result << " leads to use_left_half = " << use_left_half << " and use_right_half = " << use_right_half << std::endl; + + // Return the three grid lines which define the triangle that encloses our point + // If we didn't find an intersection above, all 6 grid lines will be returned + if (use_left_half) { + s.push_back(std::make_pair(norm_z, NR::Point(grid->origin[NR::X], y_proj_along_z_max))); + s.push_back(std::make_pair(norm_x, NR::Point(grid->origin[NR::X], y_proj_along_x_min))); + s.push_back(std::make_pair(component_vectors[NR::X], NR::Point(x_max, 0))); + } + + if (use_right_half) { + s.push_back(std::make_pair(norm_z, NR::Point(grid->origin[NR::X], y_proj_along_z_min))); + s.push_back(std::make_pair(norm_x, NR::Point(grid->origin[NR::X], y_proj_along_x_max))); + s.push_back(std::make_pair(component_vectors[NR::X], NR::Point(x_min, 0))); + } + return s; } diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index db4648ec0..183b299d1 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -886,10 +886,15 @@ CanvasXYGridSnapper::_getSnapLines(NR::Point const &p) const } NR::Coord rounded; + NR::Point point_on_line; + rounded = Inkscape::Util::round_to_upper_multiple_plus(p[i], scaled_spacing, grid->origin[i]); - s.push_back(std::make_pair(NR::Dim2(i), rounded)); + point_on_line = i ? NR::Point(0, rounded) : NR::Point(rounded, 0); + s.push_back(std::make_pair(component_vectors[i], point_on_line)); + rounded = Inkscape::Util::round_to_lower_multiple_plus(p[i], scaled_spacing, grid->origin[i]); - s.push_back(std::make_pair(NR::Dim2(i), rounded)); + point_on_line = i ? NR::Point(0, rounded) : NR::Point(rounded, 0); + s.push_back(std::make_pair(component_vectors[i], point_on_line)); } return s; |
