distances.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * $Id$
00028  *
00029  */
00030 
00033 #include <door_handle_detector/geometry/point.h>
00034 #include <door_handle_detector/geometry/distances.h>
00035 
00036 namespace cloud_geometry
00037 {
00038 
00039   namespace distances
00040   {
00042 
00047     double
00048       pointToLineDistance (const geometry_msgs::Point32 &p, const geometry_msgs::Point32 &q, const geometry_msgs::Point32 &dir)
00049     {
00050       // Calculate the distance from the point to the line
00051       // D = ||(P2-P1) x (P1-P0)|| / ||P2-P1|| = norm (cross (p2-p1, p2-p0)) / norm(p2-p1)
00052       geometry_msgs::Point32 r, p_t;
00053       r.x = q.x + dir.x;
00054       r.y = q.y + dir.y;
00055       r.z = q.z + dir.z;
00056       p_t.x = r.x - p.x;
00057       p_t.y = r.y - p.y;
00058       p_t.z = r.z - p.z;
00059 
00060       geometry_msgs::Point32 c = cross (p_t, dir);
00061       double sqr_distance = (c.x * c.x + c.y * c.y + c.z * c.z) / (dir.x * dir.x + dir.y * dir.y + dir.z * dir.z);
00062       return (sqrt (sqr_distance));
00063     }
00064 
00066 
00070     double
00071       pointToLineDistance (const geometry_msgs::Point32 &p, const std::vector<double> &line_coefficients)
00072     {
00073       // Calculate the distance from the point to the line
00074       // D = ||(P2-P1) x (P1-P0)|| / ||P2-P1|| = norm (cross (p2-p1, p2-p0)) / norm(p2-p1)
00075       std::vector<double> dir (3), r (3), p_t (3), c;
00076       dir[0] = line_coefficients[3];
00077       dir[1] = line_coefficients[4];
00078       dir[2] = line_coefficients[5];
00079 
00080       r[0] = line_coefficients[0] + dir[0];
00081       r[1] = line_coefficients[1] + dir[1];
00082       r[2] = line_coefficients[2] + dir[2];
00083       p_t[0] = r[0] - p.x;
00084       p_t[1] = r[1] - p.y;
00085       p_t[2] = r[2] - p.z;
00086 
00087       cross (p_t, dir, c);
00088       double sqr_distance = (c[0] * c[0] + c[1] * c[1] + c[2] * c[2]) / (dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]);
00089       return (sqrt (sqr_distance));
00090     }
00091 
00093 
00098     void
00099       lineToLineSegment (const std::vector<double> &line_a, const std::vector<double> &line_b, std::vector<double> &segment)
00100     {
00101       segment.resize (6);
00102 
00103       geometry_msgs::Point32 p2, q2;
00104       p2.x = line_a.at (0) + line_a.at (3);    // point + direction = 2nd point
00105       p2.y = line_a.at (1) + line_a.at (4);
00106       p2.z = line_a.at (2) + line_a.at (5);
00107       q2.x = line_b.at (0) + line_b.at (3);    // point + direction = 2nd point
00108       q2.y = line_b.at (1) + line_b.at (4);
00109       q2.z = line_b.at (2) + line_b.at (5);
00110 
00111       geometry_msgs::Point32 u, v, w;
00112 
00113       // a = x2 - x1 = line_a[1] - line_a[0]
00114       u.x = p2.x - line_a.at (0);
00115       u.y = p2.y - line_a.at (1);
00116       u.z = p2.z - line_a.at (2);
00117       // b = x4 - x3 = line_b[1] - line_b[0]
00118       v.x = q2.x - line_b.at (0);
00119       v.y = q2.y - line_b.at (1);
00120       v.z = q2.z - line_b.at (2);
00121       // c = x2 - x3 = line_a[1] - line_b[0]
00122       w.x = p2.x - line_b.at (0);
00123       w.y = p2.y - line_b.at (1);
00124       w.z = p2.z - line_b.at (2);
00125 
00126       double a = dot (u, u);
00127       double b = dot (u, v);
00128       double c = dot (v, v);
00129       double d = dot (u, w);
00130       double e = dot (v, w);
00131       double denominator = a*c - b*b;
00132       double sc, tc;
00133       // Compute the line parameters of the two closest points
00134       if (denominator < 1e-5)          // The lines are almost parallel
00135       {
00136         sc = 0.0;
00137         tc = (b > c ? d / b : e / c);  // Use the largest denominator
00138       }
00139       else
00140       {
00141         sc = (b*e - c*d) / denominator;
00142         tc = (a*e - b*d) / denominator;
00143       }
00144       // Get the closest points
00145       segment[0] = p2.x + (sc * u.x);
00146       segment[1] = p2.y + (sc * u.y);
00147       segment[2] = p2.z + (sc * u.z);
00148 
00149       segment[3] = line_b.at (0) + (tc * v.x);
00150       segment[4] = line_b.at (1) + (tc * v.y);
00151       segment[5] = line_b.at (2) + (tc * v.z);
00152     }
00153 
00154   }
00155 }


door_handle_detector
Author(s): Radu Bogdan Rusu, Marius
autogenerated on Wed Dec 11 2013 14:17:00