osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthSymbology/GeometryFactory.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarthSymbology/GeometryFactory>
00020 #include <osgEarth/GeoMath>
00021 
00022 #define LC "[GeometryFactory] "
00023 
00024 using namespace osgEarth;
00025 using namespace osgEarth::Symbology;
00026 
00027 GeometryFactory::GeometryFactory( const SpatialReference* srs ) :
00028 _srs( srs )
00029 {
00030     //nop
00031 }
00032 
00033 Geometry*
00034 GeometryFactory::createCircle(const osg::Vec3d& center,
00035                               const Linear&     radius,
00036                               unsigned          numSegments)
00037 {
00038     Polygon* geom = new Polygon();
00039 
00040     if ( numSegments == 0 )
00041     {
00042         // automatically calculate
00043         double segLen = radius.as(Units::METERS) / 8.0;
00044         double circumference = 2*osg::PI*radius.as(Units::METERS);
00045         numSegments = (unsigned)::ceil(circumference / segLen);
00046     }
00047     
00048     double segAngle = (2.0*osg::PI)/(double)numSegments;
00049 
00050     if ( _srs.valid() && _srs->isGeographic() )
00051     {
00052         double earthRadius = _srs->getEllipsoid()->getRadiusEquator();
00053         double lat = osg::DegreesToRadians(center.y());
00054         double lon = osg::DegreesToRadians(center.x());
00055         double rM  = radius.as(Units::METERS);
00056 
00057         for( unsigned i=0; i<numSegments; ++i )
00058         {
00059             double angle = segAngle * (double)i;
00060             double clat, clon;
00061             GeoMath::destination( lat, lon, angle, rM, clat, clon, earthRadius );
00062             geom->push_back( osg::Vec3d(osg::RadiansToDegrees(clon), osg::RadiansToDegrees(clat), center.z()) );
00063         }
00064     }
00065 
00066     else
00067     {
00068         double rM = radius.as(Units::METERS);
00069 
00070         for( unsigned i=0; i<numSegments; ++i )
00071         {
00072             double angle = segAngle * (double)i;
00073             double x, y;
00074             x = center.x() + sin(angle)*rM;
00075             y = center.y() + cos(angle)*rM;
00076             geom->push_back( osg::Vec3d(x, y, center.z()) );
00077         }
00078     }
00079 
00080     return geom;
00081 }
00082 
00083 Geometry*
00084 GeometryFactory::createArc(const osg::Vec3d& center,
00085                            const Linear&     radius,
00086                            const Angular&    start,
00087                            const Angular&    end,
00088                            unsigned          numSegments)
00089 {
00090     Geometry* geom = new LineString();
00091 
00092     if ( numSegments == 0 )
00093     {
00094         // automatically calculate
00095         double segLen = radius.as(Units::METERS) / 8.0;
00096         double circumference = 2*osg::PI*radius.as(Units::METERS);
00097         numSegments = (unsigned)::ceil(circumference / segLen);
00098     }
00099 
00100     double startRad = std::min( start.as(Units::RADIANS), end.as(Units::RADIANS) );
00101     double endRad   = std::max( start.as(Units::RADIANS), end.as(Units::RADIANS) );
00102     double span     = endRad - startRad;    
00103     double step     = span/(double)numSegments;
00104 
00105     if ( _srs.valid() && _srs->isGeographic() )
00106     {
00107         double earthRadius = _srs->getEllipsoid()->getRadiusEquator();
00108         double lat = osg::DegreesToRadians(center.y());
00109         double lon = osg::DegreesToRadians(center.x());
00110         double rM  = radius.as(Units::METERS);
00111 
00112         for( unsigned i=0; i<=numSegments; ++i )
00113         {
00114             double angle = startRad + step*(double)i;
00115             double clat, clon;
00116             GeoMath::destination( lat, lon, angle, rM, clat, clon, earthRadius );
00117             geom->push_back( osg::Vec3d(osg::RadiansToDegrees(clon), osg::RadiansToDegrees(clat), center.z()) );
00118         }
00119     }
00120 
00121     else
00122     {
00123         double rM = radius.as(Units::METERS);
00124 
00125         for( unsigned i=0; i<=numSegments; ++i )
00126         {
00127             double angle = startRad + step*(double)i;
00128             double x, y;
00129             x = center.x() + sin(angle)*rM;
00130             y = center.y() + cos(angle)*rM;
00131             geom->push_back( osg::Vec3d(x, y, center.z()) );
00132         }
00133     }
00134 
00135     return geom;
00136 }
00137 
00138 Geometry*
00139 GeometryFactory::createEllipse(const osg::Vec3d& center,
00140                                const Linear&     radiusMajor,
00141                                const Linear&     radiusMinor,
00142                                const Angular&    rotationAngle,
00143                                unsigned          numSegments)
00144 {
00145     Polygon* geom = new Polygon();
00146 
00147     if ( numSegments == 0 )
00148     {
00149         // automatically calculate
00150         double ravgM = 0.5*(radiusMajor.as(Units::METERS) + radiusMinor.as(Units::METERS));
00151         double segLen = ravgM / 8.0;
00152         double circumference = 2*osg::PI*ravgM;
00153         numSegments = (unsigned)::ceil(circumference / segLen);
00154     }
00155     
00156     double segAngle = 2.0*osg::PI/(double)numSegments;
00157 
00158     if ( _srs.valid() && _srs->isGeographic() )
00159     {
00160         double earthRadius = _srs->getEllipsoid()->getRadiusEquator();
00161         double lat = osg::DegreesToRadians(center.y());
00162         double lon = osg::DegreesToRadians(center.x());
00163         double a = radiusMajor.as(Units::METERS);
00164         double b = radiusMinor.as(Units::METERS);
00165         double g = rotationAngle.as(Units::RADIANS) - osg::PI_2;
00166 
00167         for( unsigned i=0; i<numSegments; ++i )
00168         {
00169             double angle = segAngle * (double)i;
00170             double t = angle - osg::PI_2;
00171             double clat, clon;
00172 
00173             double rA = (b*b-a*a)*cos(2*t - 2*g) + a*a + b*b;
00174             double q = sqrt(2.0)*a*b*sqrt(rA);
00175             double r = q/rA;
00176 
00177             GeoMath::destination( lat, lon, angle, r, clat, clon, earthRadius );
00178             geom->push_back( osg::Vec3d(osg::RadiansToDegrees(clon), osg::RadiansToDegrees(clat), center.z()) );
00179         }
00180     }
00181     else
00182     {
00183         double a = radiusMajor.as(Units::METERS);
00184         double b = radiusMinor.as(Units::METERS);
00185         double g = rotationAngle.as(Units::RADIANS) - osg::PI_2;
00186         double sing = sin(g), cosg = cos(g);
00187 
00188         for( unsigned i=0; i<numSegments; ++i )
00189         {
00190             double angle = segAngle * (double)i;
00191             double t = angle - osg::PI_2;
00192             double cost = cos(t), sint = sin(t);
00193             double x = center.x() + a*cost*cosg - b*sint*sing;
00194             double y = center.y() + a*cost*sing + b*sint*cosg;
00195 
00196             geom->push_back( osg::Vec3d(x, y, center.z()) );
00197         }
00198     }
00199 
00200     return geom;
00201 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines