#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;
}


