Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return the point of lines crossing? Lines don't always intersect

Let's say we want to make a function which calculates the intersection point of two lines. The intersection point is't always defined or unique. How to reflect that in the function's signature?

I have come up with these options:

  1. bool getIntersectionPoint ( Line& a, Line& b , Point& result );

    Returns false if lines are parallel. Otherwise returns true and writes result to the variable.

  2. Point getIntersectionPoint ( Line& a, Line& b );

    Throws an exception if lines are parallel.

[update]
If we make 2 functions bool doLinesIntersect(const Line&, const Line&); and Point twoLinesIntersection(const Line&, const Line&); the second one can still be called after the first returns false.

like image 634
Kolyunya Avatar asked Mar 26 '13 09:03

Kolyunya


1 Answers

IMHO, line intersection yields object, that's why it would be honest to have

boost::variant<Empty, Point, Line> intersect(Line const & l1, Line const & l2)

and helper functions, like

boost::optional<Point> getIntersectionPoint(Line const & l1, Line const & l2)

bool isParallel(Line const & l1, Line const & l2)

Edit: If you do not want to use boost library you can easily create simple analogues:

struct intersection_result_t
{
  enum isec_t
  {
    isec_empty, isec_point, isec_line
  }

  intersection_result_t()
    : type_(isec_empty)
  {
    new (storage_) Empty();
  }

  intersection_result_t(Empty const & e)
    : type_(isec_empty)
  {
    new (storage_) Empty(e);
  }
  intersection_result_t(Point const & p)
    : type_(isec_point)
  {
    new (storage_) Point(p);
  }
...
  intersection_result_t(intersection_result_t & ir)
    : type_(ir.type_)
  {
    switch(ir.type_)
    {
      case isec_empty:
        new (storage_) Empty(*static_cast<Empty*>(ir.storage_));
      case ....
    }
  }
private:
  void destroy()
  {
    switch(type_)
    {
      case isec_empty:
        operator delete (static_cast<Empty*>(storage_), storage_);
      case ....
    }
  }
private:
  char storage_[MAX(sizeof(Empty), sizeof(Point), sizeof(Line))];
  isec_t type_;
};

etc, etc some more switches needed. Or you can use templates. For optional just use initialized_ instead of type_ to track construction state.

like image 120
kassak Avatar answered Oct 05 '22 12:10

kassak