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