00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef _MSC_VER
00026 #include <windows_config.h>
00027 #else
00028 #include <config.h>
00029 #endif
00030
00031 #include "Position2D.h"
00032 #include "Line2D.h"
00033 #include "GeomHelper.h"
00034 #include <cassert>
00035
00036 #ifdef CHECK_MEMORY_LEAKS
00037 #include <foreign/nvwa/debug_new.h>
00038 #endif // CHECK_MEMORY_LEAKS
00039
00040
00041
00042
00043
00044
00045 Line2D::Line2D() {}
00046
00047
00048 Line2D::Line2D(const Position2D &p1, const Position2D &p2)
00049 : myP1(p1), myP2(p2) {}
00050
00051
00052 Line2D::~Line2D() {}
00053
00054
00055 void
00056 Line2D::extrapolateBy(SUMOReal length) {
00057 SUMOReal oldlen = myP1.distanceTo(myP2);
00058 SUMOReal x1 = myP1.x() - (myP2.x() - myP1.x()) * (length) / oldlen;
00059 SUMOReal y1 = myP1.y() - (myP2.y() - myP1.y()) * (length) / oldlen;
00060 SUMOReal x2 = myP2.x() - (myP1.x() - myP2.x()) * (length) / oldlen;
00061 SUMOReal y2 = myP2.y() - (myP1.y() - myP2.y()) * (length) / oldlen;
00062 myP1 = Position2D(x1, y1);
00063 myP2 = Position2D(x2, y2);
00064 }
00065
00066
00067 void
00068 Line2D::extrapolateFirstBy(SUMOReal length) {
00069 myP1 = GeomHelper::extrapolate_first(myP1, myP2, length);
00070 }
00071
00072
00073 void
00074 Line2D::extrapolateSecondBy(SUMOReal length) {
00075 myP2 = GeomHelper::extrapolate_second(myP1, myP2, length);
00076 }
00077
00078 const Position2D &
00079 Line2D::p1() const {
00080 return myP1;
00081 }
00082
00083
00084 const Position2D &
00085 Line2D::p2() const {
00086 return myP2;
00087 }
00088
00089
00090 Position2D
00091 Line2D::getPositionAtDistance(SUMOReal offset) const {
00092 SUMOReal length = myP1.distanceTo(myP2);
00093 if (length==0) {
00094 if (offset!=0) {
00095 throw 1;
00096 }
00097 return myP1;
00098 }
00099 SUMOReal x = myP1.x() + (myP2.x() - myP1.x()) / length * offset;
00100 SUMOReal y = myP1.y() + (myP2.y() - myP1.y()) / length * offset;
00101
00102
00103 return Position2D(x, y);
00104 }
00105
00106
00107 void
00108 Line2D::move2side(SUMOReal amount) {
00109 std::pair<SUMOReal, SUMOReal> p = GeomHelper::getNormal90D_CW(myP1, myP2, amount);
00110 myP1.add(p.first, p.second);
00111 myP2.add(p.first, p.second);
00112 }
00113
00114
00115 DoubleVector
00116 Line2D::intersectsAtLengths(const Position2DVector &v) {
00117 Position2DVector p = v.intersectsAtPoints(myP1, myP2);
00118 DoubleVector ret;
00119 for (size_t i=0; i<p.size(); i++) {
00120 ret.push_back(myP1.distanceTo(p[i]));
00121 }
00122 return ret;
00123 }
00124
00125
00126 SUMOReal
00127 Line2D::atan2Angle() const {
00128 return atan2(myP1.x()-myP2.x(), myP1.y()-myP2.y());
00129 }
00130
00131
00132 SUMOReal
00133 Line2D::atan2DegreeAngle() const {
00134 return (SUMOReal) atan2(myP1.x()-myP2.x(), myP1.y()-myP2.y()) *(SUMOReal) 180.0 / (SUMOReal) PI;
00135 }
00136
00137
00138 SUMOReal
00139 Line2D::atan2PositiveAngle() const {
00140 SUMOReal angle = atan2Angle();
00141 if (angle<0) {
00142 angle = (SUMOReal) PI * (SUMOReal) 2.0 + angle;
00143 }
00144 return angle;
00145 }
00146
00147 Position2D
00148 Line2D::intersectsAt(const Line2D &l) const {
00149 return GeomHelper::intersection_position(myP1, myP2, l.myP1, l.myP2);
00150 }
00151
00152
00153 bool
00154 Line2D::intersects(const Line2D &l) const {
00155 return GeomHelper::intersects(myP1, myP2, l.myP1, l.myP2);
00156 }
00157
00158
00159 SUMOReal
00160 Line2D::length() const {
00161 return sqrt(
00162 (myP1.x()-myP2.x())*(myP1.x()-myP2.x())
00163 +
00164 (myP1.y()-myP2.y())*(myP1.y()-myP2.y()));
00165 }
00166
00167
00168 void
00169 Line2D::add(SUMOReal x, SUMOReal y) {
00170 myP1.add(x, y);
00171 myP2.add(x, y);
00172 }
00173
00174
00175 void
00176 Line2D::add(const Position2D &p) {
00177 myP1.add(p.x(), p.y());
00178 myP2.add(p.x(), p.y());
00179 }
00180
00181
00182 void
00183 Line2D::sub(SUMOReal x, SUMOReal y) {
00184 myP1.sub(x, y);
00185 myP2.sub(x, y);
00186 }
00187
00188
00189
00190 Line2D &
00191 Line2D::reverse() {
00192 Position2D tmp(myP1);
00193 myP1 = myP2;
00194 myP2 = tmp;
00195 return *this;
00196 }
00197
00198
00199 SUMOReal
00200 Line2D::intersectsAtLength(const Line2D &v) {
00201 Position2D pos =
00202 GeomHelper::intersection_position(myP1, myP2, v.myP1, v.myP2);
00203 return GeomHelper::nearest_position_on_line_to_point(myP1, myP2, pos);
00204 }
00205
00206
00207 void
00208 Line2D::rotateAtP1(SUMOReal rot) {
00209 Position2D p = myP2;
00210 p.sub(myP1);
00211 p.reshiftRotate(0, 0, rot);
00212 p.add(myP1);
00213 myP2 = p;
00214 }
00215
00216
00217 void
00218 Line2D::rotateAround(const Position2D &at, SUMOReal rot) {
00219 myP1.add(-at.x(), -at.y());
00220 myP2.add(-at.x(), -at.y());
00221 {
00222 SUMOReal x = myP1.x() * cos(rot) + myP1.y() * sin(rot);
00223 SUMOReal y = myP1.y() * cos(rot) - myP1.x() * sin(rot);
00224 myP1 = Position2D(x, y);
00225 }
00226 {
00227 SUMOReal x = myP2.x() * cos(rot) + myP2.y() * sin(rot);
00228 SUMOReal y = myP2.y() * cos(rot) - myP2.x() * sin(rot);
00229 myP2 = Position2D(x, y);
00230 }
00231 myP1.add(at.x(), at.y());
00232 myP2.add(at.x(), at.y());
00233 }
00234
00235
00236
00237