ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

line2d.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "math/line2d.h"
00024 #include "math/rect2d.h"
00025 
00026 namespace Math {
00027 
00028 Line2d::Line2d() :
00029     _a(0), _b(0), _c(0) {
00030 
00031 }
00032 
00033 Line2d::Line2d(const Vector2d &direction, const Vector2d &point) {
00034     Vector2d d = direction;
00035     if (fabsf(d.getX()) > 0.0001f) {
00036         _a = d.getY() / d.getX();
00037         _b = -1;
00038     } else {
00039         _a = 1;
00040         _b = 0;
00041     }
00042 
00043     if (_b == 0) {
00044         _c = -point.getX();
00045     } else {
00046         _c = point.getY() - (d.getY() / d.getX()) * point.getX();
00047     }
00048 }
00049 
00050 Line2d Line2d::getPerpendicular(const Vector2d &point) const {
00051     Vector2d v(1, _b / _a);
00052 
00053     return Line2d(v, point);
00054 }
00055 
00056 Vector2d Line2d::getDirection() const {
00057     return Vector2d(1, _a);
00058 }
00059 
00060 float Line2d::getDistanceTo(const Vector2d &point, Vector2d *intersection) const {
00061     float dist = fabsf(_a * point.getX() + _b * point.getY() + _c) / sqrt(_a * _a + _b * _b);
00062 
00063     if (intersection) {
00064         intersectsLine(getPerpendicular(point), intersection);
00065     }
00066     return dist;
00067 }
00068 
00069 bool Line2d::intersectsLine(const Line2d &line, Vector2d *pos) const {
00070     //  if (*this == line) {
00071     //      return false;
00072     //  }
00073 
00074     float a = _a;
00075     float b = _b;
00076     float c = _c;
00077 
00078     float d = line._a;
00079     float e = line._b;
00080     float f = line._c;
00081 
00082     float x, y;
00083 
00084     const float det = a * e - b * d;
00085 
00086     if (fabsf(det) < 0.0001f) {
00087         return false;
00088     }
00089 
00090     x = (-c * e + b * f) / det;
00091     y = (-a * f + c * d) / det;
00092 
00093     if (pos)
00094         *pos = Vector2d(x, y);
00095 
00096     return true;
00097 }
00098 
00099 bool Line2d::containsPoint(const Vector2d &point) const {
00100     float n = _a * point.getX() + _b * point.getY() + _c;
00101     return (n < 0.0001 && n > -0.0001);
00102 }
00103 
00104 float Line2d::getYatX(float x) const {
00105     return -(_a * x + _c) / _b;
00106 }
00107 
00108 Common::Debug &operator<<(Common::Debug &dbg, const Math::Line2d &line) {
00109     if (fabsf(line._a) < 0.0001f) {
00110         dbg.nospace() << "Line2d: <y = " << (-line._a / line._b) << " * x + " << -line._c / line._b << ">";
00111     } else {
00112         dbg.nospace() << "Line2d: <x = " << (-line._b / line._a) << " * y + " << -line._c / line._a << ">";
00113     }
00114 
00115     return dbg.space();
00116 }
00117 
00118 
00119 
00120 
00121 Segment2d::Segment2d() {
00122 
00123 }
00124 
00125 Segment2d::Segment2d(const Vector2d &b, const Vector2d &e) :
00126     _begin(b), _end(e) {
00127 
00128 }
00129 
00130 Segment2d::Segment2d(const Segment2d &other) {
00131     *this = other;
00132 }
00133 
00134 Vector2d Segment2d::begin() const {
00135     return _begin;
00136 }
00137 
00138 Vector2d Segment2d::end() const {
00139     return _end;
00140 }
00141 
00142 Vector2d Segment2d::middle() const {
00143     return (_begin + _end) / 2.f;
00144 }
00145 
00146 Line2d Segment2d::getLine() const {
00147     float y = _end.getY() - _begin.getY();
00148     float x = _end.getX() - _begin.getX();
00149     Vector2d v(x, y);
00150 
00151     return Line2d(v, _begin);
00152 }
00153 
00154 Line2d Segment2d::getPerpendicular(const Vector2d &point) const {
00155     return getLine().getPerpendicular(point);
00156 }
00157 
00158 bool Segment2d::intersectsSegment(const Segment2d &other, Vector2d *pos) {
00159     float denom = ((other._end.getY() - other._begin.getY()) * (_end.getX() - _begin.getX())) -
00160     ((other._end.getX() - other._begin.getX()) * (_end.getY() - _begin.getY()));
00161 
00162 
00163     float d = ((_end.getY() - _begin.getY()) * (other._end.getX() - other._begin.getX())) -
00164     ((_end.getX() - _begin.getX()) * (other._end.getY() - other._begin.getY()));
00165 
00166     float nume_a = ((other._end.getX() - other._begin.getX()) * (_begin.getY() - other._begin.getY())) -
00167     ((other._end.getY() - other._begin.getY()) * (_begin.getX() - other._begin.getX()));
00168 
00169     float nume_b = ((_end.getX() - _begin.getX()) * (other._begin.getY() - _begin.getY())) -
00170     ((_end.getY() - _begin.getY()) * (other._begin.getX() - _begin.getX()));
00171 
00172     if (denom == 0.0f) {
00173         return false;
00174     }
00175 
00176     float ua = nume_a / denom;
00177     float ub = nume_b / d;
00178 
00179     if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
00180         return false;
00181     }
00182 
00183     // Get the intersection point.
00184     if (pos)
00185         *pos = _begin + (_end - _begin) * ua;
00186 
00187     return true;
00188 }
00189 
00190 bool Segment2d::intersectsLine(const Line2d &line, Vector2d *pos) {
00191     Vector2d p;
00192     if (getLine().intersectsLine(line, &p) && containsPoint(p)) {
00193         if (pos)
00194             *pos = p;
00195         return true;
00196     }
00197 
00198     return false;
00199 }
00200 
00201 bool Segment2d::containsPoint(const Vector2d &point) const {
00202     if (getLine().containsPoint(point)) {
00203         return Rect2d(_begin, _end).containsPoint(point);
00204     }
00205 
00206     return false;
00207 }
00208 
00209 Segment2d &Segment2d::operator=(const Segment2d &other) {
00210     _begin = other._begin;
00211     _end = other._end;
00212 
00213     return *this;
00214 }
00215 
00216 }


Generated on Sat Mar 16 2019 05:01:42 for ResidualVM by doxygen 1.7.1
curved edge   curved edge