GEOS  3.3.7
CentralEndpointIntersector.h
00001 /**********************************************************************
00002  * $Id: CentralEndpointIntersector.h 3255 2011-03-01 17:56:10Z mloskot $
00003  *
00004  * GEOS - Geometry Engine Open Source
00005  * http://geos.refractions.net
00006  *
00007  * Copyright (C) 2006 Refractions Research Inc.
00008  *
00009  * This is free software; you can redistribute and/or modify it under
00010  * the terms of the GNU Lesser General Public Licence as published
00011  * by the Free Software Foundation. 
00012  * See the COPYING file for more information.
00013  *
00014  **********************************************************************
00015  *
00016  * Last port: algorithm/CentralEndpointIntersector.java rev. 1.1
00017  *
00018  **********************************************************************/
00019 
00020 #ifndef GEOS_ALGORITHM_CENTRALENDPOINTINTERSECTOR_H
00021 #define GEOS_ALGORITHM_CENTRALENDPOINTINTERSECTOR_H
00022 
00023 #include <geos/export.h>
00024 #include <geos/geom/Coordinate.h>
00025 
00026 #include <string>
00027 #include <limits>
00028 
00029 #ifdef _MSC_VER
00030 #pragma warning(push)
00031 #pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
00032 #endif
00033 
00034 // Forward declarations
00035 namespace geos {
00036         namespace geom {
00037                 //class PrecisionModel;
00038         }
00039 }
00040 
00041 namespace geos {
00042 namespace algorithm { // geos::algorithm
00043 
00063 class GEOS_DLL CentralEndpointIntersector {
00064 
00065 public: 
00066 
00067         static const geom::Coordinate& getIntersection(const geom::Coordinate& p00,
00068                         const geom::Coordinate& p01, const geom::Coordinate& p10,
00069                         const geom::Coordinate& p11)
00070         {
00071                 CentralEndpointIntersector intor(p00, p01, p10, p11);
00072                 return intor.getIntersection();
00073         }
00074 
00075         CentralEndpointIntersector(const geom::Coordinate& p00,
00076                         const geom::Coordinate& p01,
00077                         const geom::Coordinate& p10,
00078                         const geom::Coordinate& p11)
00079                 :
00080                 _pts(4)
00081         {
00082                 _pts[0]=p00;
00083                 _pts[1]=p01;
00084                 _pts[2]=p10;
00085                 _pts[3]=p11;
00086                 compute();
00087         }
00088 
00089         const geom::Coordinate& getIntersection() const
00090         {
00091                 return _intPt;
00092         }
00093 
00094 
00095 private:
00096 
00097         // This is likely overkill.. we'll be allocating heap
00098         // memory at every call !
00099         std::vector<geom::Coordinate> _pts;
00100 
00101         geom::Coordinate _intPt;
00102 
00103         void compute()
00104         {
00105                 geom::Coordinate centroid = average(_pts);
00106                 _intPt = findNearestPoint(centroid, _pts);
00107         }
00108 
00109         static geom::Coordinate average(
00110                         const std::vector<geom::Coordinate>& pts)
00111         {
00112                 geom::Coordinate avg(0, 0);
00113                 size_t n = pts.size();
00114                 if ( ! n ) return avg;
00115                 for (std::size_t i=0; i<n; ++i)
00116                 {
00117                         avg.x += pts[i].x;
00118                         avg.y += pts[i].y;
00119                 }
00120                 avg.x /= n;
00121                 avg.y /= n;
00122                 return avg;
00123         }
00124 
00135         geom::Coordinate findNearestPoint(const geom::Coordinate& p,
00136                         const std::vector<geom::Coordinate>& pts) const
00137         {
00138                 double minDist = std::numeric_limits<double>::max();
00139                 geom::Coordinate result = geom::Coordinate::getNull();
00140                 for (std::size_t i = 0, n=pts.size(); i < n; ++i) {
00141                         double dist = p.distance(pts[i]);
00142                         if (dist < minDist) {
00143                                 minDist = dist;
00144                                 result = pts[i];
00145                         }
00146                 }
00147                 return result;
00148         }
00149 };
00150 
00151 } // namespace geos::algorithm
00152 } // namespace geos
00153 
00154 #ifdef _MSC_VER
00155 #pragma warning(pop)
00156 #endif
00157 
00158 #endif // GEOS_ALGORITHM_CENTRALENDPOINTINTERSECTOR_H
00159 
00160 /**********************************************************************
00161  * $Log$
00162  **********************************************************************/
00163