/** * Classify a point with respect to an edge, i.e. left, right of edge etc. * @param pt :: A point as V2D * @param edge :: A test edge object * @returns The type of the point */ PointClassification classify(const V2D &pt, const PolygonEdge &edge) { V2D p2 = pt; const V2D &a = edge.direction(); V2D b = p2 - edge.start(); double sa = a.X() * b.Y() - b.X() * a.Y(); if (sa > 0.0) { return OnLeft; } if (sa < 0.0) { return OnRight; } if ((a.X() * b.X() < 0.0) || (a.Y() * b.Y() < 0.0)) { return Behind; } if (a.norm() < b.norm()) { return Beyond; } if (edge.start() == p2) { return Origin; } if (edge.end() == p2) { return Destination; } return Between; }
/** * Angle between this and another vector */ double V2D::angle(const V2D &other) const { double ratio = this->scalar_prod(other) / (this->norm() * other.norm()); if (ratio >= 1.0) // NOTE: Due to rounding errors, if "other" return 0.0; // is nearly the same as "this" or else if (ratio <= -1.0) // as "-this", ratio can be slightly return M_PI; // more than 1 in absolute value. // That causes acos() to return NaN. return acos(ratio); }