GP_Image_Test/src/shifting.cpp

168 lines
4.7 KiB
C++
Raw Normal View History

2024-01-26 12:45:30 -05:00
/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2024-01-28 15:52:49 -05:00
#include "blt/std/logging.h"
2024-01-26 12:45:30 -05:00
#include <shifting.h>
#include <blt/math/vectors.h>
#include <vector>
#include <blt/std/hashmap.h>
inline constexpr char from_char(char c)
{
2024-01-28 15:52:49 -05:00
return c;
2024-01-26 12:45:30 -05:00
}
2024-01-28 15:52:49 -05:00
struct vertex_data
2024-01-26 12:45:30 -05:00
{
char name;
HASHSET<char> neighbours;
2024-01-28 15:52:49 -05:00
blt::vec2 pos;
2024-01-26 12:45:30 -05:00
2024-01-28 15:52:49 -05:00
vertex_data(char name, const HASHSET<char>& n): name(from_char(name))
2024-01-26 12:45:30 -05:00
{
for (const auto& v : n)
neighbours.insert(from_char(v));
}
2024-01-28 15:52:49 -05:00
vertex_data(char name, const blt::vec2& pos): name(from_char(name)), pos(pos)
{}
2024-01-26 12:45:30 -05:00
};
2024-01-28 15:52:49 -05:00
using Point = const blt::vec2&;
bool onSegment(Point p, Point q, Point r)
{
if (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()))
return true;
return false;
}
int orientation(Point p, Point q, Point r)
{
// for details of below formula.
int val = (q.y() - p.y()) * (r.x() - q.x()) -
(q.x() - p.x()) * (r.y() - q.y());
if (val == 0) return 0; // collinear
return (val > 0) ? 1 : 2; // clock or counterclock wise
}
bool doIntersect(Point p1, Point q1, Point p2, Point q2)
{
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are collinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and q2 are collinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are collinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are collinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
float ccw(const blt::vec2& A, const blt::vec2& B, const blt::vec2& C)
{
return (C.y() - A.y()) * (B.x() - A.x()) > (B.y() - A.y()) * (C.x() - A.x());
}
// Return true if line segments AB and CD intersect
bool intersects(const blt::vec2& A, const blt::vec2& B, const blt::vec2& C, const blt::vec2& D)
{
return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(A, B, D);
}
std::vector<vertex_data> edges = {
vertex_data{'a', HASHSET<char>{'i', 'e', 'b', 'j', 'h'}},
vertex_data{'b', HASHSET<char>{'a', 'e', 'c', 'j'}},
vertex_data{'c', HASHSET<char>{'e', 'd', 'f', 'j', 'b'}},
vertex_data{'d', HASHSET<char>{'e', 'f', 'c'}},
vertex_data{'e', HASHSET<char>{'h', 'f', 'd', 'c', 'b', 'a', 'i'}},
vertex_data{'f', HASHSET<char>{'d', 'e', 'h', 'g', 'j', 'c'}},
vertex_data{'g', HASHSET<char>{'j', 'f', 'h'}},
vertex_data{'h', HASHSET<char>{'j', 'g', 'f', 'e', 'i', 'a'}},
vertex_data{'i', HASHSET<char>{'e', 'a', 'h'}},
vertex_data{'j', HASHSET<char>{'a', 'b', 'c', 'f', 'g', 'h'}},
2024-01-26 12:45:30 -05:00
};
2024-01-28 15:52:49 -05:00
HASHSET<char>& getEdges(char c)
{
for (auto& e : edges)
if (e.name == c)
return e.neighbours;
BLT_FATAL("Failed to find character in edge set");
std::exit(2);
}
std::vector<char> order = {
from_char('f'),
from_char('d'),
from_char('c'),
from_char('g'),
from_char('j'),
from_char('b'),
from_char('e'),
from_char('i'),
from_char('a'),
from_char('h'),
};
std::vector<vertex_data> out;
bool has_intersection(Point p, char c)
{
}
void shift_right(int units)
2024-01-26 12:45:30 -05:00
{
}
2024-01-28 15:52:49 -05:00
void calculate_ordering()
{
out.push_back(vertex_data{order.back(), blt::vec2{0, 0}});
out.back().neighbours = getEdges(out.back().name);
order.pop_back();
out.push_back(vertex_data{order.back(), blt::vec2{2, 0}});
out.back().neighbours = getEdges(out.back().name);
order.pop_back();
while (!order.empty())
{
}
}