geometry.py
Go to the documentation of this file.
00001 #
00002 # Copyright (c) 2009, Georgia Tech Research Corporation
00003 # All rights reserved.
00004 #
00005 # Redistribution and use in source and binary forms, with or without
00006 # modification, are permitted provided that the following conditions are met:
00007 #     * Redistributions of source code must retain the above copyright
00008 #       notice, this list of conditions and the following disclaimer.
00009 #     * Redistributions in binary form must reproduce the above copyright
00010 #       notice, this list of conditions and the following disclaimer in the
00011 #       documentation and/or other materials provided with the distribution.
00012 #     * Neither the name of the Georgia Tech Research Corporation nor the
00013 #       names of its contributors may be used to endorse or promote products
00014 #       derived from this software without specific prior written permission.
00015 #
00016 # THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS'' AND
00017 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 # DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH BE LIABLE FOR ANY DIRECT, INDIRECT,
00020 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00021 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00022 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00023 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00024 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 #
00027 
00028 #  \author Advait Jain (Healthcare Robotics Lab, Georgia Tech.)
00029 
00030 # convex_hull requires Shapely
00031 import shapely.geometry as sg
00032 
00033 import math
00034 import numpy as np
00035 
00036 # inverse of a 2x2 matrix
00037 def inverse_2x2(a):
00038     return 1/np.linalg.det(a) * np.matrix([[a[1,1],-a[0,1]],[-a[1,0],a[0,0]]])
00039 
00040 ## compute point that is the projection of q onto the line passing
00041 # through p1 and p2. 2x1 or 3x1 np matrices.
00042 def project_point_on_line(q, p1, p2):
00043     v1 = p2-p1
00044     v1 = v1 / np.linalg.norm(v1)
00045     v2 = q - p1
00046     p = p1 + np.dot(v2.A1, v1.A1) * v1
00047     return p
00048 
00049 # @param pts - Nx2 np array
00050 # @return Mx2 np array
00051 def convex_hull(pts):
00052     mp = sg.MultiPoint(pts)
00053     ch = mp.convex_hull
00054     if ch.__class__ == sg.polygon.Polygon:
00055         hull_pts = np.array(ch.exterior.coords)
00056     else:
00057         hull_pts = np.array(ch.coords)
00058     return hull_pts
00059 
00060 # distance of a point from a curve defined by a series of points.
00061 # pt - 2x1 or 3x1 np matrix
00062 # pts_list - list of array-like of len 2 or 3
00063 def distance_from_curve(pt, pts_list):
00064     spt = sg.Point(pt.A1)
00065     s_pts_list = sg.LineString(pts_list)
00066     return s_pts_list.distance(spt)
00067 
00068 # distance of a point from a curve defined by a series of points.
00069 # pt - 2x1 or 3x1 np matrix
00070 # pts_list - list of array-like of len 2 or 3
00071 def distance_along_curve(pt, pts_list):
00072     spt = sg.Point(pt.A1)
00073     s_pts_list = sg.LineString(pts_list)
00074     return s_pts_list.project(spt)
00075 
00076 ## return a point on the curve that is closest to the given point.
00077 # pt - 2x1 or 3x1 np matrix
00078 # pts_list - list of array-like of len 2 or 3
00079 def project_point_on_curve(pt, pts_list):
00080     spt = sg.Point(pt.A1)
00081     s_pts_list = sg.LineString(pts_list)
00082     d = s_pts_list.project(spt)
00083     spt_new = s_pts_list.interpolate(d)
00084     return np.matrix(spt_new.coords[0]).T
00085 
00086 ## return point dist away from the start of the curve, measured along
00087 # the curve.
00088 # pts_list - list of array-like of len 2 or 3
00089 # dist - float.
00090 # normalized - see Shapely.interpolate documentation.
00091 def get_point_along_curve(pts_list, dist, normalized=False):
00092     s_pts_list = sg.LineString(pts_list)
00093     spt_new = s_pts_list.interpolate(dist, normalized)
00094     return np.matrix(spt_new.coords[0]).T
00095 
00096 def test_convex_hull():
00097     pp.axis('equal')
00098     pts = np.random.uniform(size=(40,2))
00099     h_pts = convex_hull(pts)
00100     print 'h_pts.shape:', h_pts.shape
00101 
00102     all_x = pts[:,0]
00103     all_y = pts[:,1]
00104     x_ch, y_ch = h_pts[:,0], h_pts[:,1]
00105 
00106     pp.plot(all_x, all_y, '.b', ms=5)
00107     pp.plot(x_ch, y_ch, '.-g', ms=5)
00108 
00109     pp.show()
00110 
00111 def test_distance_from_curve():
00112     pt = np.matrix([0.8, 0.5, 0.3]).T
00113     pts_l = [[0, 0.], [1,0.], [1.,1.]]
00114     print 'distance_from_curve:', distance_from_curve(pt, pts_l)
00115     print 'distance_along_curve:', distance_along_curve(pt, pts_l)
00116     
00117     pt_proj = project_point_on_curve(pt, pts_l)
00118 
00119     pp.axis('equal')
00120     pp.plot([pt[0,0]], [pt[1,0]], 'go', ms=7)
00121     pp.plot([pt_proj[0,0]], [pt_proj[1,0]], 'yo', ms=7)
00122     pp.plot(*zip(*pts_l))
00123     pp.show()
00124 
00125 # finds a,b such that x=ay+b (good if expected slope is large)
00126 # x, y -- nX1 matrices
00127 # returns a,b,mean residual
00128 def fit_line_high_slope(x, y):
00129     A = np.column_stack((y, np.ones((y.shape[0],1))))
00130     x,resids,rank,s = np.linalg.linalg.lstsq(A, x)
00131     a = x[0,0]
00132     b = x[1,0]
00133     return a,b,resids/y.shape[0]
00134 
00135 # finds a,b such that y=ax+b (good if expected slope is small)
00136 # x, y -- nX1 matrices
00137 # returns a,b,mean residual
00138 def fit_line_low_slope(x, y):
00139     A = np.column_stack((x, np.ones((x.shape[0],1))))
00140     y,resids,rank,s = np.linalg.linalg.lstsq(A, y)
00141     a = y[0,0]
00142     b = y[1,0]
00143     return a,b,resids/x.shape[0]
00144 
00145 
00146 if __name__ == '__main__':
00147     import matplotlib.pyplot as pp
00148 
00149     test_project_point_on_line = True
00150     test_convex_hull_flag = False
00151     test_distance_from_curve_flag = False
00152 
00153     if test_project_point_on_line:
00154         p1 = np.matrix([2,3.]).T
00155         p2 = np.matrix([-1.5,6.3]).T
00156         q = np.matrix([1.5,7.3]).T
00157 
00158         p = project_point_on_line(q, p1, p2)
00159 
00160         x = [p1[0,0], p2[0,0]]
00161         y = [p1[1,0], p2[1,0]]
00162         pp.plot(x, y, 'b', label='line')
00163 
00164         x = [q[0,0], p[0,0]]
00165         y = [q[1,0], p[1,0]]
00166         pp.plot(x, y, '-r.', ms=10, label='projection')
00167 
00168         pp.axis('equal')
00169         pp.legend()
00170         pp.show()
00171 
00172     if test_convex_hull_flag:
00173         test_convex_hull()
00174 
00175     if test_distance_from_curve_flag:
00176         test_distance_from_curve()
00177 
00178 
00179 


hrl_lib
Author(s): Cressel Anderson, Travis Deyle, Advait Jain, Hai Nguyen, Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 11:34:06