Code

Color Matrix Filter:
[inkscape.git] / src / perspective-line.cpp
index 158ddd47bd2a2b7be83a0c77a51704622d3cc600..90857e6d5ecd10fac2ee887f5db8dfda20068e66 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "perspective-line.h"
+#include "desktop.h"
 
 namespace Box3D {
 
@@ -19,6 +20,7 @@ PerspectiveLine::PerspectiveLine (NR::Point const &pt, Box3D::Axis const axis, P
         Line (pt, *(perspective->get_vanishing_point(axis)), true)
 {
     g_assert (perspective != NULL);
+    g_assert (Box3D::is_single_axis_direction (axis));
 
     if (perspective->get_vanishing_point(axis)->state == VP_INFINITE) {
         this->set_direction(perspective->get_vanishing_point(axis)->v_dir);
@@ -49,6 +51,40 @@ NR::Point PerspectiveLine::meet(Line const &line)
     return *intersect(line); // works since intersect() does not return NR::Nothing()
 }
 
+NR::Point PerspectiveLine::pt_with_given_cross_ratio (NR::Point const &C, NR::Point const &D, double gamma)
+{
+    if (persp->get_vanishing_point (vp_dir)->is_finite()) {
+        NR::Point V (*persp->get_vanishing_point (vp_dir));
+        return fourth_pt_with_given_cross_ratio (V, C, D, gamma);
+    } else {
+        if (fabs (gamma - 1) < epsilon) {
+            g_warning ("Cannot compute point with given cross ratio.\n");
+            return NR::Point (0.0, 0.0);
+        }
+        Line line (C, D);
+        double lambda_C = line.lambda (C);
+        double lambda_D = line.lambda (D);
+        return line.point_from_lambda ((lambda_D - gamma * lambda_C) / (1 - gamma));
+    }
+}
+
+NR::Maybe<NR::Point> PerspectiveLine::intersection_with_viewbox (SPDesktop *desktop)
+{
+    NR::Rect vb = desktop->get_display_area();
+    /* remaining viewbox corners */
+    NR::Point ul (vb.min()[NR::X], vb.max()[NR::Y]);
+    NR::Point lr (vb.max()[NR::X], vb.min()[NR::Y]);
+
+    std::pair <NR::Point, NR::Point> e = side_of_intersection (vb.min(), lr, vb.max(), ul, this->pt, this->v_dir);
+    if (e.first == e.second) {
+        // perspective line lies outside the canvas
+        return NR::Nothing();
+    }
+
+    Line line (e.first, e.second);
+    return this->intersect (line);
+}
+
 } // namespace Box3D 
  
 /*