59 lines
1.6 KiB
C++
59 lines
1.6 KiB
C++
#include <cmath>
|
|
#include <algorithm>
|
|
#include "cross-checker.h"
|
|
|
|
|
|
// 计算向量叉积的方向
|
|
// 返回值:
|
|
// 0 表示三点共线
|
|
// 1 表示逆时针方向(正)
|
|
// -1 表示顺时针方向(负)
|
|
int cross_checker::Point::orientation(const Point& p, const Point& q, const Point& r)
|
|
{
|
|
const double val = (q.x - p.x) * (r.y - p.y) - (r.x - p.x) * (q.y - p.y);
|
|
if (std::fabs(val) < 1e-9) return 0; // 共线
|
|
return (val > 0) ? 1 : -1;
|
|
}
|
|
|
|
bool cross_checker::Point::onSegment(const Point& p, const Point& q, const Point& r)
|
|
{
|
|
return q.x <= std::max(p.x, r.x) && q.x >= std::min(p.x, r.x) &&
|
|
q.y <= std::max(p.y, r.y) && q.y >= std::min(p.y, r.y);
|
|
}
|
|
|
|
bool cross_checker::Line::intersect(const Line& other)
|
|
{
|
|
const int o1 = Point::orientation(startPoint, endPoint, other.startPoint);
|
|
const int o2 = Point::orientation(startPoint, endPoint, other.endPoint);
|
|
const int o3 = Point::orientation(other.startPoint, other.endPoint, startPoint);
|
|
const int o4 = Point::orientation(other.startPoint, other.endPoint, endPoint);
|
|
|
|
// 普通情况:跨立实验
|
|
if (o1 != o2 && o3 != o4)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 特殊情况:共线
|
|
if (o1 == 0 && Point::onSegment(startPoint, other.startPoint, endPoint))
|
|
{
|
|
return true;
|
|
}
|
|
if (o2 == 0 && Point::onSegment(startPoint, other.endPoint, endPoint))
|
|
{
|
|
return true;
|
|
}
|
|
if (o3 == 0 && Point::onSegment(other.startPoint, startPoint, other.endPoint))
|
|
{
|
|
return true;
|
|
}
|
|
if (o4 == 0 && Point::onSegment(other.startPoint, endPoint, other.endPoint))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|