SpherePackingScenarioGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ChannelPrinterHelper.h
Go to the documentation of this file.
00001 /*
00002  * ChannelPrinterHelper.h
00003  *
00004  *  Created on: Mar 10, 2012
00005  *      Author: michael
00006  */
00007 
00008 #ifndef CHANNELPRINTERHELPER_H_
00009 #define CHANNELPRINTERHELPER_H_
00010 
00011 #include "algorithms/geometries/Channel.h"
00012 #include <vector>
00013 #include "tarch/la/Vector.h"
00014 
00015 #define DIMENSIONS 2
00016 
00017 namespace xml {
00018   namespace twoD {
00019     class ChannelPrinterHelper;
00020 
00021     struct SubDomain {
00022       SubDomain(
00023           algorithms::geometries::Channel domain,
00024           tarch::la::Vector<2,int>    intPosition
00025           )
00026       :_domain(domain),
00027        _intPosition(intPosition)
00028        {}
00029 
00030       inline double getXMin() const {
00031         return _domain.getCenterPositionX()-_domain.getLength()/2.0;
00032       }
00033 
00034       inline double getXMax() const {
00035         return _domain.getCenterPositionX()+_domain.getLength()/2.0;
00036       }
00037 
00038       inline double getYMin() const {
00039         return _domain.getCenterPositionY()-_domain.getWidth()/2.0;
00040       }
00041 
00042       inline double getYMax() const {
00043         return _domain.getCenterPositionY()+_domain.getWidth()/2.0;
00044       }
00045 
00046       algorithms::geometries::Channel _domain;
00047       std::vector<algorithms::geometries::Channel*> _channels;
00048       tarch::la::Vector<2,int>    _intPosition;
00049     };
00050 
00051     struct Point{
00052       Point(double _x, double _y):
00053         x(_x),
00054         y(_y)
00055       {}
00056 
00057       Point():
00058         x(0),
00059         y(0)
00060       {}
00061 
00062       Point(tarch::la::Vector<2, double> point):
00063         x(point[0]),
00064         y(point[1])
00065       {}
00066 
00067       std::string toString() const {
00068         std::stringstream ss;
00069         ss << "Point (" <<x <<"/" <<x <<")";
00070         return ss.str();
00071       }
00072 
00073       bool operator==(const Point& rhs) const {
00074         return (tarch::la::equals(rhs.x, x) && tarch::la::equals(rhs.y, y) ) ? true: false;
00075       }
00076 
00077       double x, y;
00078     };
00079 
00080     inline std::ostream& operator<<(std::ostream& out, const Point& p) {
00081       out <<"P(" <<p.x <<"/" <<p.y <<")";
00082       return out;
00083     }
00084 
00085     struct Line{
00086       Line(double m, double t)
00087       :_a(m),
00088        _b(t){
00089       }
00090 
00091       Line()
00092       :_a(1.0),
00093        _b(0.0){
00094       }
00095 
00096       Line(Point A, Point B)
00097       :_a( (A.y-B.y)/(A.x-B.x) ),
00098        _b( B.y - _a*B.x ){
00099       }
00100 
00101       double _a, _b;
00102 
00103       double getY(double x) {
00104         return x*_a + _b;
00105       }
00106 
00107       Point getIntersectionPoint(Line lineToIntersect) {
00108         Point p;
00109         p.x = (lineToIntersect._b - _b)/(_a - lineToIntersect._a);
00110         p.y = getY(p.x);
00111         return p;
00112       }
00113 
00114       double getXPosOfPointProjected(Point p){
00115         assertion(_a != 0);
00116         double t2 = p.y + p.x/_a;
00117         double m2 = -1.0/_a;
00118         double value = (t2 - _b)/(_a - m2);
00119         return value;
00120       }
00121     };
00122 
00123   } /* namespace geometries */
00124 } /* namespace algorithms */
00125 
00126 
00127 class xml::twoD::ChannelPrinterHelper {
00128   typedef algorithms::geometries::Channel Channel;
00129 
00130 public:
00131   ChannelPrinterHelper();
00132   virtual
00133   ~ChannelPrinterHelper();
00134 
00135 
00136 
00137   std::vector< xml::twoD::SubDomain >
00138   sortChannelsWithRespectToSubdomains(
00139       std::vector<Channel*>& channels,
00140       const unsigned int& subDivPerDim
00141   ) const;
00142 
00143   std::vector<xml::twoD::SubDomain>
00144   generateSubDomains(
00145       const unsigned int& subDivPerDim
00146   ) const;
00147 
00148   bool areRectanglesSeparatedAlongXOrYAxis(
00149       const Channel& unrotatedChannel,
00150       Channel& rotatedChannel
00151   ) const {
00152     /* get borders of unrotated channel */
00153     double leftBorderUnrotChannel  = unrotatedChannel.getCenterPositionX() - unrotatedChannel.getLength()/2.0;
00154     double rightBorderUnrotChannel = unrotatedChannel.getCenterPositionX() + unrotatedChannel.getLength()/2.0;
00155     double lowerBorderUnrotChannel = unrotatedChannel.getCenterPositionY() - unrotatedChannel.getLength()/2.0;
00156     double upperBorderUnrotChannel = unrotatedChannel.getCenterPositionY() + unrotatedChannel.getLength()/2.0;
00157 
00158     // check intersection of x-axis - return false if no intersection occurs
00159     tarch::la::Vector<4,double> boundingBox = rotatedChannel.getBoundingBox();
00160     if( !(leftBorderUnrotChannel  < boundingBox(Channel::RIGHT) ||
00161         rightBorderUnrotChannel < boundingBox(Channel::LEFT) ))
00162       return false;
00163 
00164     // check intersection of y-axis - return false if no intersection occurs
00165     if( !(lowerBorderUnrotChannel > boundingBox(Channel::TOP) ||
00166         upperBorderUnrotChannel < boundingBox(Channel::BOTTOM) ))
00167       return false;
00168 
00169     return true;
00170   }
00171 
00172   bool areProjectionsSeparated(
00173       const Channel& unrotatedChannel,
00174       Channel& rotatedChannel
00175   ) const {
00176     assertionEquals(unrotatedChannel.getOrientation(), 0.0);
00177     // test if rotation is multiple of Pi
00178     // if yes we can ommit this test - and don't have to worry about special cases in it :)
00179     double test = rotatedChannel.getOrientation()/(M_PI/2.0);
00180 
00181     if(!tarch::la::equals(test-(int)test,0.0)) {
00182       // check if the 1D projection intersects
00183       /* get borders of unrotated channel */
00184       double leftBorderUnrotChannel  = unrotatedChannel.getCenterPositionX() - unrotatedChannel.getLength()/2.0;
00185       double rightBorderUnrotChannel = unrotatedChannel.getCenterPositionX() + unrotatedChannel.getLength()/2.0;
00186       double lowerBorderUnrotChannel = unrotatedChannel.getCenterPositionY() - unrotatedChannel.getLength()/2.0;
00187       double upperBorderUnrotChannel = unrotatedChannel.getCenterPositionY() + unrotatedChannel.getLength()/2.0;
00188 
00189       std::vector<tarch::la::Vector<2, double> > positions = rotatedChannel.getSortedVertices();
00190 
00191       // Line on which we will project
00192       Line projectionLine(
00193           rotatedChannel._sinOrientation/rotatedChannel._cosOrientation, 0.0);
00194 
00200       Line
00201       leftBottom  = Line(Point(positions[Channel::LEFT]), Point(positions[Channel::BOTTOM])),
00202       rightTop    = Line(Point(positions[Channel::RIGHT]), Point(positions[Channel::TOP]));
00203 
00204       Point
00205       unrotLeftBottom  = Point(leftBorderUnrotChannel,lowerBorderUnrotChannel),
00206       unrotRightTop    = Point(rightBorderUnrotChannel,upperBorderUnrotChannel);
00207 
00211       double rotLeft = projectionLine.getIntersectionPoint(leftBottom).x;
00212       double rotRight= projectionLine.getIntersectionPoint(rightTop).x;
00213 
00217       double unrotLeft = projectionLine.getXPosOfPointProjected(unrotLeftBottom);
00218       double unrotRight= projectionLine.getXPosOfPointProjected(unrotRightTop);
00219 
00220       return areRegionsSeparated(rotLeft,rotRight,unrotLeft,unrotRight);
00221     }
00222 
00223     return true;
00224   }
00225 
00229   inline bool areRegionsSeparated(
00230       const double& region1LowerBound,
00231       const double& region1UpperBound,
00232       const double& region2LowerBound,
00233       const double& region2UpperBound) const {
00234     assertion(region1LowerBound < region1UpperBound);
00235     assertion(region2LowerBound < region2UpperBound);
00236     return
00237         !(region1LowerBound >= region2LowerBound && region1LowerBound <= region2UpperBound) &&
00238         !(region1UpperBound >= region2LowerBound && region1UpperBound <= region2UpperBound);
00239   }
00240 
00247   bool doChannelsIntersect(
00248       const Channel& unrotatedChannel,
00249       Channel& rotatedChannel
00250   ) const {
00251     if(areRectanglesSeparatedAlongXOrYAxis(unrotatedChannel, rotatedChannel))
00252       return false;
00253 
00254     if(areProjectionsSeparated(unrotatedChannel, rotatedChannel))
00255       return false;
00256 
00257     /* check x-axis separating axis */
00258     return true;
00259   }
00260 };
00261 
00262 #endif /* CHANNELPRINTERHELPER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines