For lines I would use the Hesse Normal Form for each segment calculate the distance and select or discard that line.
The Hesse Normal Form
/// Hesse Normal Form
/// \NOTE: Since negative distances from the origin are accepted, it is almost
/// a Hesse Normal Form, only)
template<class ScalarType>
class HesseNormalForm2D
{
public:
typedef ScalarType Scalar;
typedef Normal2D<Scalar> Normal;
typedef Vector2D<Scalar> Vector;
typedef Point2D<Scalar> Point;
typedef Line2D<Scalar> Line;
public:
/// An invalid line initialized with NaN.
static HesseNormalForm2D nan() { return HesseNormalForm2D(Normal::nan(), Scalar::nan()); }
/// An undefined line.
HesseNormalForm2D() {}
/// A line defined by a normal and a distance form the origin.
explicit HesseNormalForm2D(const Normal& n, const Scalar& d)
: m_n(n), m_d(d)
{}
/// The Hesse Normal Form of a line.
/// ATTENTION The scalar value d of the line may be negative.
explicit HesseNormalForm2D(const Point& p, const Vector& v) {
m_n = -orthonormal(v);
m_d = scalar_product(m_n, Vector(p));
}
/// The Hesse Normal Form of a line.
/// ATTENTION The scalar value d of the line may be negative.
explicit HesseNormalForm2D(const Point& p0, const Point& p1) {
m_n = -orthonormal(p1 - p0);
m_d = scalar_product(m_n, Vector(p0));
}
/// The Hesse Normal Form of a line.
/// ATTENTION The scalar value d of the line may be negative.
explicit HesseNormalForm2D(const Line&);
/// The normal.
const Normal& n() const { return m_n; }
/// The normal.
Normal& n() { return m_n; }
/// The distance from the origin.
const Scalar& d() const { return m_d; }
/// The distance from the origin.
Scalar& d() { return m_d; }
/// The distance of a point to the line.
/// \NOTE The point x on the line L with the smallest distance to p is:
/// x = p - L(p) * L.n()
Scalar operator () (const Point& p) const {
return scalar_product(Vector(p), n()) - d();
}
private:
Normal m_n;
Scalar m_d;
};
To generalize it you would have a different class considering the different attributes you need (Line, Arc, ... ).