You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.2 KiB
C
82 lines
2.2 KiB
C
|
1 month ago
|
/*------------------------------------------------------------------------------
|
||
|
|
* Copyright (c) 2023 by Bai Bing (seread@163.com)
|
||
|
|
* See COPYING file for copying and redistribution conditions.
|
||
|
|
*
|
||
|
|
* Alians IT Studio.
|
||
|
|
*----------------------------------------------------------------------------*/
|
||
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "_Define.h"
|
||
|
|
#include "utils/EssentiallyEqual.h"
|
||
|
|
|
||
|
|
#include "ASPoint.h"
|
||
|
|
|
||
|
|
namespace ais
|
||
|
|
{
|
||
|
|
template <typename PT = ais::Point>
|
||
|
|
inline int cross(const PT &a, const PT &b, const PT &c)
|
||
|
|
{
|
||
|
|
return ais::dcmp((b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y));
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename PT = ais::Point>
|
||
|
|
inline bool line_cross(const PT &p1, const PT &p2, const PT &q1, const PT &q2)
|
||
|
|
{
|
||
|
|
if (std::max(p1.x, p2.x) >= std::min(q1.x, q2.x) &&
|
||
|
|
std::max(q1.x, q2.x) >= std::min(p1.x, p2.x) &&
|
||
|
|
std::max(p1.y, p2.y) >= std::min(q1.y, q2.y) &&
|
||
|
|
std::max(q1.y, q2.y) >= std::min(p1.y, p2.y))
|
||
|
|
{
|
||
|
|
if (cross(p1, p2, q1) * cross(p1, p2, q2) <= 0 && cross(q1, q2, p1) * cross(q1, q2, p2) <= 0)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename PT = ais::Point>
|
||
|
|
inline bool line_intersect(const std::vector<PT> &line, const std::vector<PT> &polygon)
|
||
|
|
{
|
||
|
|
for (auto &p : line)
|
||
|
|
{
|
||
|
|
if (p.in_polygon(polygon))
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t n = polygon.size();
|
||
|
|
for (auto i = 0; i != n; i++)
|
||
|
|
if (line_cross(line[0], line[1], polygon[i], polygon[((i + 1) % n)]))
|
||
|
|
return true;
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <typename PT = ais::Point>
|
||
|
|
bool polygon_intersect(const std::vector<PT> &p1, const std::vector<PT> &p2)
|
||
|
|
{
|
||
|
|
for (auto &p : p1)
|
||
|
|
{
|
||
|
|
if (p.in_polygon(p2))
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (auto &p : p2)
|
||
|
|
{
|
||
|
|
if (p.in_polygon(p1))
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t n = p1.size();
|
||
|
|
size_t m = p2.size();
|
||
|
|
|
||
|
|
for (auto i = 0; i != n; i++)
|
||
|
|
for (auto j = 0; j != m; j++)
|
||
|
|
if (line_cross(p1[i], p1[((i + 1) % n)], p2[j], p2[((j + 1) % m)]))
|
||
|
|
return true;
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|