Ejemplo n.º 1
0
bool
gde::geom::algorithm::do_intersects_v2(const gde::geom::core::line_segment& s1,
                                       const gde::geom::core::line_segment& s2)
{
  double a = (s2.p1.x - s1.p1.x) * (s1.p2.y - s1.p1.y) - (s2.p1.y - s1.p1.y) * (s1.p2.x - s1.p1.x);
  double b = (s2.p2.x - s1.p1.x) * (s1.p2.y - s1.p1.y) - (s2.p2.y - s1.p1.y) * (s1.p2.x - s1.p1.x);

// if the endpoints of the second segment lie on the opposite
  if((a != 0.0) && (b != 0.0) && same_signs(a, b))
    return false;

  double c = (s1.p1.x - s2.p1.x) * (s2.p2.y - s2.p1.y) - (s1.p1.y - s2.p1.y) * (s2.p2.x - s2.p1.x);
  double d = (s1.p2.x - s2.p1.x) * (s2.p2.y - s2.p1.y) - (s1.p2.y - s2.p1.y) * (s2.p2.x - s2.p1.x);

// if the endpoints of the first segment lie on the opposite
  if((c != 0.0) && (d != 0.0) && same_signs(c, d))
    return false;

// are the segments collinear?
  double det = a - b;

  if(det == 0.0)
    return do_collinear_segments_intersects(s1, s2);

// the segments intersect
  return true;
}
Ejemplo n.º 2
0
bool
gde::geom::algorithm::do_intersects_v1(const gde::geom::core::line_segment& s1,
                                       const gde::geom::core::line_segment& s2)
{
// compute general line equation for segment s1
  double a1 = s1.p2.y - s1.p1.y;
  double b1 = s1.p1.x - s1.p2.x;
  double c1 = (s1.p2.x * s1.p1.y) - (s1.p1.x * s1.p2.y);

  double r3 = a1 * s2.p1.x + b1 * s2.p1.y + c1;
  double r4 = a1 * s2.p2.x + b1 * s2.p2.y + c1;

// if both points from segment s2 are to the sime side of line defined by segment s1,
// we are sure s2 can not intersects s1
  if((r3 != 0.0) && (r4 != 0.0) && same_signs(r3, r4))
    return false;

// compute general line equation for segment s2
  double a2 = s2.p2.y - s2.p1.y;
  double b2 = s2.p1.x - s2.p2.x;
  double c2 = (s2.p2.x * s2.p1.y) - (s2.p1.x * s2.p2.y);

  double r1 = a2 * s1.p1.x + b2 * s1.p1.y + c2;
  double r2 = a2 * s1.p2.x + b2 * s1.p2.y + c2;

// if both points from segment s1 are to the sime side of line defined by segment s2,
// we are sure s1 can not intersects s2
  if((r1 != 0.0) && (r2 != 0.0) && same_signs(r1, r2))
    return false;

// ok: we know tha segments may overlap or cross at a single point!
  return true;
}
Ejemplo n.º 3
0
		// Unlike with a % b, the result always has the same sign as the divisor.
		constexpr int modulus(int a, int b)
		{
			int result = a % b;
			if (result && !same_signs(result, b))
				result += b;
			return result;
		}
Ejemplo n.º 4
0
		// Returns the result of the integer division rounded up / towards +∞.
		constexpr int div_ceil(int a, int b)
		{
			// +1 if a / b > 0
			int result = a / b;
			if (a % b)
				result += same_signs(a, b);
			return result;
		}
Ejemplo n.º 5
0
		// Returns the result of the integer division rounded down / towards -∞.
		constexpr int div_floor(int a, int b)
		{
			// -1 if a / b < 0
			int result = a / b;
			if (a % b)
				result -= !same_signs(a, b);
			return result;
		}
Ejemplo n.º 6
0
		// Returns the result of the division rounded towards infinity/away from zero.
		constexpr int div_towards_infinity(int a, int b)
		{
			// +1 if a / b > 0
			// -1 if a / b < 0
			int result = a / b;
			if (a % b)
				result += same_signs(a, b) ? 1 : -1;
			return result;
		}
Ejemplo n.º 7
0
gde::geom::algorithm::segment_relation_type
gde::geom::algorithm::compute_intesection_v2(const gde::geom::core::line_segment& s1,
                                             const gde::geom::core::line_segment& s2,
                                             gde::geom::core::point& first,
                                             gde::geom::core::point& second)
{
  double a = (s2.p1.x - s1.p1.x) * (s1.p2.y - s1.p1.y) - (s2.p1.y - s1.p1.y) * (s1.p2.x - s1.p1.x);
  double b = (s2.p2.x - s1.p1.x) * (s1.p2.y - s1.p1.y) - (s2.p2.y - s1.p1.y) * (s1.p2.x - s1.p1.x);

// if the endpoints of the second segment lie on the opposite
  if((a != 0.0) && (b != 0.0) && same_signs(a, b))
    return DISJOINT;

  double c = (s1.p1.x - s2.p1.x) * (s2.p2.y - s2.p1.y) - (s1.p1.y - s2.p1.y) * (s2.p2.x - s2.p1.x);
  double d = (s1.p2.x - s2.p1.x) * (s2.p2.y - s2.p1.y) - (s1.p2.y - s2.p1.y) * (s2.p2.x - s2.p1.x);

// if the endpoints of the first segment lie on the opposite
  if((c != 0.0) && (d != 0.0) && same_signs(c, d))
    return DISJOINT;

  double det = a - b;

  if(det == 0.0)  // are the segments collinear?
  {
    if(do_collinear_segments_intersects(s1, s2) == false)
      return DISJOINT;

// and we know they intersects: let's order the segments and find out intersection(s)
    const gde::geom::core::point* pts[4];
    pts[0] = &s1.p1;
    pts[1] = &s1.p2;
    pts[2] = &s2.p1;
    pts[3] = &s2.p2;

    std::sort(pts, pts + 4, point_cmp);

// at least they will share one point
    first = *pts[1];

// and if segments touch in a single point they are equal
    if((pts[1]->x == pts[2]->x) && (pts[1]->y == pts[2]->y))
      return TOUCH;

// otherwise, the middle points are the intesections
    second = *pts[2];

    return OVERLAP;
  }

// ok: they are not collinear!

  double tdet = -c;

// the denominator of the parameter must be positive
  if(det < 0.0)
  {
    det = -det;
    tdet = -tdet;
  }

// compute intersection point
  double alpha = tdet / det;

  first.x = s1.p1.x + alpha * (s1.p2.x - s1.p1.x);
  first.y = s1.p1.y + alpha * (s1.p2.y - s1.p1.y);

  return CROSS;
}
Ejemplo n.º 8
0
gde::geom::algorithm::segment_relation_type
gde::geom::algorithm::compute_intesection_v1(const gde::geom::core::line_segment& s1,
                                             const gde::geom::core::line_segment& s2,
                                             gde::geom::core::point& first,
                                             gde::geom::core::point& second)
{
  double a1 = s1.p2.y - s1.p1.y;
  double b1 = s1.p1.x - s1.p2.x;
  double c1 = (s1.p2.x * s1.p1.y) - (s1.p1.x * s1.p2.y);

  double r3 = a1 * s2.p1.x + b1 * s2.p1.y + c1;
  double r4 = a1 * s2.p2.x + b1 * s2.p2.y + c1;

// if both points from segment s2 are to the sime side of line defined by segment s1,
// we are sure s2 can not intersects s1
  if((r3 != 0.0) && (r4 != 0.0) && same_signs(r3, r4))
    return DISJOINT;

// compute general line equation for segment s2
  double a2 = s2.p2.y - s2.p1.y;
  double b2 = s2.p1.x - s2.p2.x;
  double c2 = (s2.p2.x * s2.p1.y) - (s2.p1.x * s2.p2.y);

  double r1 = a2 * s1.p1.x + b2 * s1.p1.y + c2;
  double r2 = a2 * s1.p2.x + b2 * s1.p2.y + c2;

// if both points from segment s1 are to the sime side of line defined by segment s2,
// we are sure s1 can not intersects s2
  if((r1 != 0.0) && (r2 != 0.0) && same_signs(r1, r2))
    return DISJOINT;

// setting the denominator
  double denom = a1 * b2 - a2 * c1;

  if(denom == 0.0)  // are they collinear?
  {
    if(do_collinear_segments_intersects(s1, s2) == false)
      return DISJOINT;
// and we know they intersects: let's order the segments and find out intersection(s)
    const gde::geom::core::point* pts[4];
    pts[0] = &s1.p1;
    pts[1] = &s1.p2;
    pts[2] = &s2.p1;
    pts[3] = &s2.p2;

    std::sort(pts, pts + 4, point_cmp);

// at least they will share one point
    first = *pts[1];

// and if segments touch in a single point they are equal
    if((pts[1]->x == pts[2]->x) && (pts[1]->y == pts[2]->y))
      return TOUCH;

// otherwise, the middle points are the intesections
    second = *pts[2];

    return OVERLAP;
  }

// ok: they are not collinear!
  double offset = denom < 0.0 ? - denom / 2.0 : denom / 2.0;

// setting the numerator
// compute intersection point
  double num_alpha = b1 * c2 - b2 * c1;
  first.x = (num_alpha < 0.0 ? num_alpha - offset : num_alpha + offset) / denom;

  double num_beta = a2 * c1 - a1 * c2;
  first.y = (num_beta < 0.0 ? num_beta - offset : num_beta + offset) / denom;

  return CROSS;
}
Ejemplo n.º 9
0
/// \{
template<class T> inline bool opposite_signs(const T & a, const T & b) { return not same_signs(a, b); }