/* * Checks whether two lines intersect or not * @see http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ * adapted from line_line_intersection */ std::pair<int, int> FlatRay::IntersectsRatio(const FlatRay &that) const { std::pair<int, int> r; r.second = vector.CrossProduct(that.vector); if (r.second == 0) // lines are parallel return r; const FlatGeoPoint delta = that.point - point; r.first = delta.CrossProduct(that.vector); if ((sgn(r.first) * sgn(r.second) < 0) || (abs(r.first) > abs(r.second))) { // outside first line r.second = 0; return r; } const int ub = delta.CrossProduct(vector); if ((sgn(ub) * sgn(r.second) < 0) || (abs(ub) > abs(r.second))) { // outside second line r.second = 0; return r; } // inside both lines return r; }
static FlatGeoPoint nearest_point_convex(const SearchPointVector& spv, const FlatGeoPoint &p3) { unsigned distance_min = 0-1; SearchPointVector::const_iterator i_best = spv.end(); // find nearest point in vector for (SearchPointVector::const_iterator i = spv.begin(); i!= spv.end(); ++i) { unsigned d_this = p3.distance_sq_to(i->get_flatLocation()); if (d_this<distance_min) { distance_min = d_this; i_best = i; } } FlatGeoPoint pc = i_best->get_flatLocation(); // find nearest point on this segment FlatGeoPoint pa = segment_nearest_point(spv,i_best,p3); if (!(pa == pc)) { unsigned d_seg = pa.distance_sq_to(p3); if (d_seg < distance_min) { distance_min = d_seg; pc = pa; } } // find nearest point on previous segment SearchPointVector::const_iterator i_prev; if (i_best == spv.begin()) { i_prev = spv.end()-1; } else { i_prev = i_best-1; } FlatGeoPoint pb = segment_nearest_point(spv,i_prev,p3); if (!(pb == pc)) { unsigned d_seg = pb.distance_sq_to(p3); if (d_seg < distance_min) { distance_min = d_seg; pc = pb; } } return pc; }
bool FlatTriangleFan::IsInside(FlatGeoPoint p) const { if (!bounding_box.IsInside(p)) return false; bool inside = false; for (auto i = vs.begin(), j = std::prev(vs.end()), end = vs.end(); i != end; j = i++) { if ((i->y > p.y) == (j->y > p.y)) continue; const FlatGeoPoint ji = *j - *i; const FlatGeoPoint pi = p - *i; if (pi.CrossProduct(ji) < 0) inside = !inside; } return inside; }
static FlatGeoPoint nearest_point(const FlatGeoPoint &p1, const FlatGeoPoint &p2, const FlatGeoPoint &p3) { const FlatGeoPoint p12 = p2-p1; const fixed rsq(p12.dot(p12)); if (!positive(rsq)) { return p1; } const FlatGeoPoint p13 = p3-p1; const fixed numerator(p13.dot(p12)); if (!positive(numerator)) { return p1; } else if (numerator>= rsq) { return p2; } else { fixed t = numerator/rsq; return p1+(p2-p1)*t; } }
gcc_pure static FlatGeoPoint NearestPoint(const FlatGeoPoint &p1, const FlatGeoPoint &p2, const FlatGeoPoint &p3) { const FlatGeoPoint p12 = p2-p1; const double rsq(p12.DotProduct(p12)); if (rsq <= 0) return p1; const FlatGeoPoint p13 = p3-p1; const double numerator(p13.DotProduct(p12)); if (numerator <= 0) { return p1; } else if (numerator>= rsq) { return p2; } else { double t = numerator/rsq; return p1+(p2-p1)*t; } }
/* * Checks whether two lines * intersect or not * @see http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ * adapted from line_line_intersection * */ fixed FlatRay::intersects (const FlatRay &that) const { const int denom = vector.cross(that.vector); if (denom == 0) { // lines are parallel return -fixed_one; } const FlatGeoPoint delta = that.point-point; const int ua = delta.cross(that.vector); if ((sgn(ua)*sgn(denom)<0) || (abs(ua)>abs(denom))) { // outside first line return -fixed_one; } const int ub = delta.cross(vector); if ((sgn(ub)*sgn(denom)<0) || (abs(ub)>abs(denom))) { // outside second line return -fixed_one; } // inside both lines return ((fixed)ua)/denom; }
static FlatGeoPoint nearest_point_nonconvex(const SearchPointVector& spv, const FlatGeoPoint &p3) { unsigned distance_min = 0-1; SearchPointVector::const_iterator i_best = spv.end(); for (SearchPointVector::const_iterator i = spv.begin(); i!= spv.end(); ++i) { FlatGeoPoint pa = segment_nearest_point(spv,i,p3); unsigned d_this = p3.distance_sq_to(pa); if (d_this<distance_min) { distance_min = d_this; i_best = i; } } return i_best->get_flatLocation(); }
SearchPointVector::const_iterator SearchPointVector::NearestIndexConvex(const FlatGeoPoint &p3) const { unsigned distance_min = 0 - 1; const_iterator i_best = end(); // find nearest point in vector for (auto i = begin(); i != end(); ++i) { unsigned d_this = p3.DistanceSquared(i->GetFlatLocation()); if (d_this < distance_min) { distance_min = d_this; i_best = i; } } return i_best; }
static FlatGeoPoint NearestPointNonConvex(const SearchPointVector& spv, const FlatGeoPoint &p3) { unsigned distance_min = 0-1; FlatGeoPoint point_best; for (SearchPointVector::const_iterator i = spv.begin(); i!= spv.end(); ++i) { FlatGeoPoint pa = SegmentNearestPoint(spv,i,p3); unsigned d_this = p3.distance_sq_to(pa); if (d_this<distance_min) { distance_min = d_this; point_best = pa; } } return point_best; }
/** * Get distance in internal flat projected units (fast) * * @param f Point to get distance to * * @return Distance in flat units */ unsigned FlatDistanceTo(const FlatGeoPoint &f) const { assert(flat_location_initialised); return flat_location.Distance(f); }
/** * Calculate the "flat" square distance. This is cheaper than * flat_distance(), because it does not need to calculate the square * root. */ gcc_pure unsigned FlatSquareDistanceTo(const SearchPoint& sp) const { return flat_location.DistanceSquared(sp.flat_location); }
/** * Calculate flat earth distance between two points * * @param sp Point to measure distance from * * @return Distance in projected units */ gcc_pure unsigned flat_distance(const SearchPoint& sp) const { return flatLocation.Distance(sp.flatLocation); }
unsigned FlatGeoPoint::DistanceSquared(const FlatGeoPoint &sp) const { const FlatGeoPoint delta = *this - sp; return delta.DotProduct(delta); }