feat: add quiz 3 cross-checker.
This commit is contained in:
58
cross-checker/src/cross-checker.cpp
Normal file
58
cross-checker/src/cross-checker.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user