From ab3bec75b6a6408451a99137fff688d07a55b94b Mon Sep 17 00:00:00 2001 From: cilix42 Date: Sat, 1 Sep 2007 13:29:40 +0000 Subject: [PATCH] Infrastructure to set direction of infinite VPs (now adjustable by some shortcuts; this may be removed later on) --- src/box3d-context.cpp | 30 ++++++++++++++++++++++++++++++ src/box3d.cpp | 17 +++++++++++++++++ src/box3d.h | 1 + src/line-geometry.cpp | 5 ----- src/line-geometry.h | 4 ++++ src/perspective3d.cpp | 35 +++++++++++++++++++++++++++++++++++ src/perspective3d.h | 2 ++ src/vanishing-point.h | 2 ++ 8 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index 8b8b1ca99..2abf0112f 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -451,6 +451,36 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven ret = TRUE; break; + case GDK_bracketright: + inkscape_active_document()->current_perspective->rotate (Box3D::X, -10); + ret = true; + break; + + case GDK_bracketleft: + inkscape_active_document()->current_perspective->rotate (Box3D::X, 10); + ret = true; + break; + + case GDK_parenright: + inkscape_active_document()->current_perspective->rotate (Box3D::Y, -10); + ret = true; + break; + + case GDK_parenleft: + inkscape_active_document()->current_perspective->rotate (Box3D::Y, 10); + ret = true; + break; + + case GDK_braceright: + inkscape_active_document()->current_perspective->rotate (Box3D::Z, -10); + ret = true; + break; + + case GDK_braceleft: + inkscape_active_document()->current_perspective->rotate (Box3D::Z, 10); + ret = true; + break; + case GDK_I: Box3D::Perspective3D::print_debugging_info(); ret = true; diff --git a/src/box3d.cpp b/src/box3d.cpp index 5e67f46ab..1942ea3d6 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -798,6 +798,23 @@ sp_3dbox_link_to_existing_paths (SP3DBox *box, Inkscape::XML::Node *repr) { } } +void +sp_3dbox_reshape_after_VP_rotation (SP3DBox *box, Box3D::Axis axis) +{ + Box3D::Perspective3D *persp = inkscape_active_document()->get_persp_of_box (box); + Box3D::VanishingPoint *vp = persp->get_vanishing_point (axis); + + guint c1 = (axis == Box3D::Z) ? 1 : sp_3dbox_get_front_corner_id (box); // hack + guint c2 = c1 ^ axis; + NR::Point v = box->corners[c1] - box->corners[c2]; + double dist = NR::L2 (v) * ((NR::dot (v, vp->v_dir) < 0) ? 1 : -1); // "directed" distance + + Box3D::PerspectiveLine pline (box->corners[c1], axis, persp); + NR::Point pt = pline.point_from_lambda (dist); + + sp_3dbox_move_corner_in_Z_direction (box, c2, pt, axis == Box3D::Z); +} + void sp_3dbox_move_corner_in_XY_plane (SP3DBox *box, guint id, NR::Point pt, Box3D::Axis axes) { diff --git a/src/box3d.h b/src/box3d.h index 3d52c96d1..1e567ded9 100644 --- a/src/box3d.h +++ b/src/box3d.h @@ -77,6 +77,7 @@ void sp_3dbox_update_curves (SP3DBox *box); void sp_3dbox_link_to_existing_paths (SP3DBox *box, Inkscape::XML::Node *repr); void sp_3dbox_set_ratios (SP3DBox *box, Box3D::Axis axes = Box3D::XYZ); void sp_3dbox_switch_front_face (SP3DBox *box, Box3D::Axis axis); +void sp_3dbox_reshape_after_VP_rotation (SP3DBox *box, Box3D::Axis axis); void sp_3dbox_move_corner_in_XY_plane (SP3DBox *box, guint id, NR::Point pt, Box3D::Axis axes = Box3D::XY); void sp_3dbox_move_corner_in_Z_direction (SP3DBox *box, guint id, NR::Point pt, bool constrained = true); void sp_3dbox_reshape_after_VP_toggling (SP3DBox *box, Box3D::Axis axis); diff --git a/src/line-geometry.cpp b/src/line-geometry.cpp index 7b6ba0449..872e9ed6b 100644 --- a/src/line-geometry.cpp +++ b/src/line-geometry.cpp @@ -91,11 +91,6 @@ double Line::lambda (NR::Point const pt) return lambda; } -inline static double determinant (NR::Point const &a, NR::Point const &b) -{ - return (a[NR::X] * b[NR::Y] - a[NR::Y] * b[NR::X]); -} - /* The coordinates of w with respect to the basis {v1, v2} */ std::pair coordinates (NR::Point const &v1, NR::Point const &v2, NR::Point const &w) { diff --git a/src/line-geometry.h b/src/line-geometry.h index fc8f157e9..e678c4031 100644 --- a/src/line-geometry.h +++ b/src/line-geometry.h @@ -55,6 +55,10 @@ protected: NR::Coord d0; }; +inline double determinant (NR::Point const &a, NR::Point const &b) +{ + return (a[NR::X] * b[NR::Y] - a[NR::Y] * b[NR::X]); +} std::pair coordinates (NR::Point const &v1, NR::Point const &v2, NR::Point const &w); bool lies_in_sector (NR::Point const &v1, NR::Point const &v2, NR::Point const &w); bool lies_in_quadrangle (NR::Point const &A, NR::Point const &B, NR::Point const &C, NR::Point const &D, NR::Point const &pt); diff --git a/src/perspective3d.cpp b/src/perspective3d.cpp index 8b1b3863d..9321af356 100644 --- a/src/perspective3d.cpp +++ b/src/perspective3d.cpp @@ -180,6 +180,41 @@ Perspective3D::set_vanishing_point (Box3D::Axis const dir, VanishingPoint const } } +void +Perspective3D::set_infinite_direction (Box3D::Axis axis, NR::Point const dir) +{ + Box3D::Axis axis1 = Box3D::get_remaining_axes (axis).first; + Box3D::Axis axis2 = Box3D::get_remaining_axes (axis).second; + Box3D::VanishingPoint *vp1 = get_vanishing_point (axis1); + Box3D::VanishingPoint *vp2 = get_vanishing_point (axis2); + if (fabs (Box3D::determinant (vp1->v_dir, dir)) < Box3D::epsilon || + fabs (Box3D::determinant (vp2->v_dir, dir)) < Box3D::epsilon) { + // This is an ad-hoc correction; we should fix this more thoroughly + double a = NR::atan2 (dir) + 0.01; + this->set_infinite_direction (axis, NR::Point (cos (a), sin (a))); // we call this function again in case there is another conflict (which is unlikely, but possible) + return; + } + + get_vanishing_point (axis)->set_infinite_direction (dir); +} + +void +Perspective3D::rotate (Box3D::Axis const axis, double const angle) +{ + Box3D::VanishingPoint *vp = get_vanishing_point (axis); + if (!vp->is_finite()) { + double a = NR::atan2 (vp->v_dir) * 180/M_PI; + a += angle; + a *= M_PI/180; + this->set_infinite_direction (axis, NR::Point (cos (a), sin (a))); + for (GSList *i = this->boxes; i != NULL; i = i->next) { + sp_3dbox_reshape_after_VP_rotation (SP_3DBOX (i->data), axis); + sp_3dbox_set_z_orders_later_on (SP_3DBOX (i->data)); + } + update_box_reprs(); + } +} + Axis Perspective3D::get_axis_of_VP (VanishingPoint *vp) { diff --git a/src/perspective3d.h b/src/perspective3d.h index 8c63cf42e..a431e1f99 100644 --- a/src/perspective3d.h +++ b/src/perspective3d.h @@ -35,6 +35,8 @@ public: Axis get_axis_of_VP (VanishingPoint *vp); void set_vanishing_point (Box3D::Axis const dir, VanishingPoint const &pt); void set_vanishing_point (Box3D::Axis const dir, gdouble pt_x, gdouble pt_y, gdouble dir_x, gdouble dir_y, VPState st); + void set_infinite_direction (Box3D::Axis axis, NR::Point const dir); + void rotate (Box3D::Axis const dir, double const angle); void add_box (SP3DBox *box); void remove_box (const SP3DBox *box); bool has_box (const SP3DBox *box) const; diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 7d53fa89d..428bb49ad 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -59,6 +59,8 @@ public: (*this)[NR::Y] = pt[NR::Y]; } inline void set_pos(const double pt_x, const double pt_y) { (*this)[NR::X] = pt_x; (*this)[NR::Y] = pt_y; } + inline void set_infinite_direction (const NR::Point dir) { v_dir = dir; } + inline void set_infinite_direction (const double dir_x, const double dir_y) { v_dir = NR::Point (dir_x, dir_y); } bool is_finite() const; VPState toggle_parallel(); -- 2.30.2