SpherePackingScenarioGenerator
|
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_ */