|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // } 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 00020 00021 // =========================================================================== 00022 // included modules 00023 // =========================================================================== 00024 00025 #ifdef _MSC_VER 00026 #include <windows_config.h> 00027 #else 00028 #include <config.h> 00029 #endif 00030 00031 #include "Position.h" 00032 #include "Line.h" 00033 #include "GeomHelper.h" 00034 #include <utils/common/ToString.h> 00035 #include <cassert> 00036 00037 #ifdef CHECK_MEMORY_LEAKS 00038 #include <foreign/nvwa/debug_new.h> 00039 #endif // CHECK_MEMORY_LEAKS 00040 00041 00042 // =========================================================================== 00043 // member method definitions 00044 // =========================================================================== 00045 00046 Line::Line() {} 00047 00048 00049 Line::Line(const Position& p1, const Position& p2) 00050 : myP1(p1), myP2(p2) {} 00051 00052 00053 Line::~Line() {} 00054 00055 00056 void 00057 Line::extrapolateBy(SUMOReal length) { 00058 SUMOReal factor = length / myP1.distanceTo(myP2); 00059 Position offset = (myP2 - myP1) * factor; 00060 myP1.sub(offset); 00061 myP2.add(offset); 00062 } 00063 00064 00065 void 00066 Line::extrapolateFirstBy(SUMOReal length) { 00067 myP1 = GeomHelper::extrapolate_first(myP1, myP2, length); 00068 } 00069 00070 00071 void 00072 Line::extrapolateSecondBy(SUMOReal length) { 00073 myP2 = GeomHelper::extrapolate_second(myP1, myP2, length); 00074 } 00075 00076 const Position& 00077 Line::p1() const { 00078 return myP1; 00079 } 00080 00081 00082 const Position& 00083 Line::p2() const { 00084 return myP2; 00085 } 00086 00087 00088 Position 00089 Line::getPositionAtDistance(SUMOReal offset) const { 00090 SUMOReal length = myP1.distanceTo(myP2); 00091 if (length==0) { 00092 if (offset!=0) { 00093 throw InvalidArgument("Invalid offset " + toString(offset) + " for Line with length " + toString(length));; 00094 } 00095 return myP1; 00096 } 00097 return myP1 + ((myP2 - myP1) * (offset/length)); 00098 } 00099 00100 00101 void 00102 Line::move2side(SUMOReal amount) { 00103 std::pair<SUMOReal, SUMOReal> p = GeomHelper::getNormal90D_CW(myP1, myP2, amount); 00104 myP1.add(p.first, p.second); 00105 myP2.add(p.first, p.second); 00106 } 00107 00108 00109 DoubleVector 00110 Line::intersectsAtLengths(const PositionVector& v) { 00111 PositionVector p = v.intersectsAtPoints(myP1, myP2); 00112 DoubleVector ret; 00113 for (size_t i=0; i<p.size(); i++) { 00114 ret.push_back(myP1.distanceTo(p[int(i)])); 00115 } 00116 return ret; 00117 } 00118 00119 00120 SUMOReal 00121 Line::atan2Angle() const { 00122 return atan2(myP1.x()-myP2.x(), myP1.y()-myP2.y()); 00123 } 00124 00125 00126 SUMOReal 00127 Line::atan2DegreeAngle() const { 00128 return (SUMOReal) atan2(myP1.x()-myP2.x(), myP1.y()-myP2.y()) *(SUMOReal) 180.0 / (SUMOReal) PI; 00129 } 00130 00131 00132 SUMOReal 00133 Line::atan2PositiveAngle() const { 00134 SUMOReal angle = atan2Angle(); 00135 if (angle<0) { 00136 angle = (SUMOReal) PI * (SUMOReal) 2.0 + angle; 00137 } 00138 return angle; 00139 } 00140 00141 Position 00142 Line::intersectsAt(const Line& l) const { 00143 return GeomHelper::intersection_position(myP1, myP2, l.myP1, l.myP2); 00144 } 00145 00146 00147 bool 00148 Line::intersects(const Line& l) const { 00149 return GeomHelper::intersects(myP1, myP2, l.myP1, l.myP2); 00150 } 00151 00152 00153 SUMOReal 00154 Line::length() const { 00155 return sqrt( 00156 (myP1.x()-myP2.x())*(myP1.x()-myP2.x()) 00157 + 00158 (myP1.y()-myP2.y())*(myP1.y()-myP2.y())); 00159 } 00160 00161 00162 void 00163 Line::add(SUMOReal x, SUMOReal y) { 00164 myP1.add(x, y); 00165 myP2.add(x, y); 00166 } 00167 00168 00169 void 00170 Line::add(const Position& p) { 00171 myP1.add(p.x(), p.y()); 00172 myP2.add(p.x(), p.y()); 00173 } 00174 00175 00176 void 00177 Line::sub(SUMOReal x, SUMOReal y) { 00178 myP1.sub(x, y); 00179 myP2.sub(x, y); 00180 } 00181 00182 00183 00184 Line& 00185 Line::reverse() { 00186 Position tmp(myP1); 00187 myP1 = myP2; 00188 myP2 = tmp; 00189 return *this; 00190 } 00191 00192 00193 SUMOReal 00194 Line::intersectsAtLength(const Line& v) { 00195 Position pos = 00196 GeomHelper::intersection_position(myP1, myP2, v.myP1, v.myP2); 00197 return GeomHelper::nearest_position_on_line_to_point(myP1, myP2, pos); 00198 } 00199 00200 00201 void 00202 Line::rotateAtP1(SUMOReal rot) { 00203 Position p = myP2; 00204 p.sub(myP1); 00205 p.reshiftRotate(0, 0, rot); 00206 p.add(myP1); 00207 myP2 = p; 00208 } 00209 00210 00211 void 00212 Line::rotateAround(const Position& at, SUMOReal rot) { 00213 myP1.add(-at.x(), -at.y()); 00214 myP2.add(-at.x(), -at.y()); 00215 { 00216 SUMOReal x = myP1.x() * cos(rot) + myP1.y() * sin(rot); 00217 SUMOReal y = myP1.y() * cos(rot) - myP1.x() * sin(rot); 00218 myP1 = Position(x, y); 00219 } 00220 { 00221 SUMOReal x = myP2.x() * cos(rot) + myP2.y() * sin(rot); 00222 SUMOReal y = myP2.y() * cos(rot) - myP2.x() * sin(rot); 00223 myP2 = Position(x, y); 00224 } 00225 myP1.add(at.x(), at.y()); 00226 myP2.add(at.x(), at.y()); 00227 } 00228 00229 00230 /****************************************************************************/ 00231