This repository has been archived on 2025-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MemMAPR-MKR/src/Mesh.cpp
2025-05-15 23:26:58 +03:00

146 lines
3.8 KiB
C++

#include "Mesh.hpp"
Mesh::Mesh(Object& _obj, double _step) : obj(_obj), step(_step) {
for (double y = 0.0; y <= _obj.Height(); y += _step) {
mesh.push_back(std::vector<Node*>());
for (double x = 0.0; x <= _obj.Width(); x += _step) {
mesh.back().push_back(new Node(x, y));
}
}
LinkX();
LinkY();
Adapt();
}
void Mesh::VisualizeMesh(std::string name) {
std::ofstream data_file(name);
data_file << "# Coordinates\n";
data_file << "# Format: x y\n";
for (const auto& row : mesh) {
for (const auto& node : row) {
data_file << node->X() << " " << node->Y() << "\n";
}
}
data_file.close();
}
void Mesh::LinkX() {
for (int i = 0; i < mesh.size(); i++) {
mesh[i][0]->LinkX(nullptr, mesh[i][1]);
for (int j = 1; j < mesh[i].size() - 1; j++)
mesh[i][j]->LinkX(mesh[i][j - 1], mesh[i][j + 1]);
mesh[i].back()->LinkX(mesh[i][mesh[i].size() - 2], nullptr);
}
for (int i = 0; i < mesh.size(); i++)
hlines.push_back(mesh[i][0]);
}
void Mesh::LinkY() {
for (int j = 0; j < mesh[0].size(); j++) {
mesh[0][j]->LinkY(nullptr, mesh[1][j]);
for (int i = 1; i < mesh.size() - 1; i++)
mesh[i][j]->LinkY(mesh[i - 1][j], mesh[i + 1][j]);
mesh[mesh.size() - 1][j]->LinkY(mesh[mesh.size() - 2][j], nullptr);
}
for (int i = 0; i < mesh[0].size(); i++)
vlines.push_back(mesh[0][i]);
}
void Mesh::Adapt() {
for (int i = 0; i < mesh.size(); i++) {
int s = mesh[i].size();
for (int j = 0; j < s; j++) {
if (!obj.Inhere(mesh[i][j]->X(), mesh[i][j]->Y())) {
Delnode(i, j);
j--;
s--;
}
}
}
}
void Mesh::Delnode(int i, int j) {
Node* node = mesh[i][j];
/* Âû÷èñëÿþòñÿ ãðàíèöû ôîðìû ïî îñÿì X è Y */
double bndX1 = obj.FillX(node->X(), node->Y()).first;
double bndX2 = obj.FillX(node->X(), node->Y()).second;
double bndY1 = obj.FillY(node->X(), node->Y()).first;
double bndY2 = obj.FillY(node->X(), node->Y()).second;
/* ÃÓ ôîðìû */
int btype = obj.Who(node->X(), node->Y())->GetB();
if (node->l()) {
// Åñëè ëåâûé ñîñåä íå ëåæèò íà ãðàíèöå ïðèìèòèâà
if (node->l()->X() != bndX2 && node->l()->X() != bndX1) {
if (bndX1 != bndX2) {
/* Ñîçäàåì óçëû íà ãðàíèöàõ bndX2 è bndX1 ñ ÃÓ btype */
Node* left = new Node(bndX2, node->Y(), btype);
Node* right = new Node(bndX1, node->Y(), btype);
node->l()->r() = left;
if (node->r())
node->r()->l() = right;
/* Óñòàíàâëèâàåì ñâÿçè äëÿ íîâûõ óçëîâ ïî îñè X */
left->LinkX(node->l(), right);
right->LinkX(left, node->r());
node->l() = right;
mesh[i].push_back(left);
mesh[i].push_back(right);
}
/* Åñëè ãðàíèöû ïî X ñîâïàäàþò, ñîçäàåì îäèí óçåë */
else {
Node* left = new Node(bndX2, node->Y(), btype);
node->l()->r() = left;
if (node->r())
node->r()->l() = left;
left->LinkX(node->l(), node->r());
node->l() = left;
mesh[i].push_back(left);
}
}
/* Åñëè ëåâûé ñîñåä óæå íà ãðàíèöå, ñâÿçûâàåì åãî ñ ïðàâûì ñîñåäîì */
else
node->l()->r() = node->r();
} /* Ïî àíàëîãèè ñ ëåâûì óçëîì */
if (node->r()) {
node->r()->l() = node->l();
}
if (node->d()) {
if (node->d()->Y() != bndY2 && node->d()->Y() != bndY1) {
if (bndY2 != bndY1) {
Node* down = new Node(node->X(), bndY2, btype);
Node* up = new Node(node->X(), bndY1, btype);
node->d()->u() = down;
if (node->u())
node->u()->d() = up;
down->LinkY(node->d(), up);
up->LinkY(down, node->u());
node->d() = up;
mesh[i].push_back(down);
mesh[i].push_back(up);
}
else {
Node* down = new Node(node->X(), bndY2, btype);
node->d()->u() = down;
if (node->u())
node->u()->d() = down;
down->LinkY(node->d(), node->u());
node->d() = down;
mesh[i].push_back(down);
}
}
else
node->d()->u() = node->u();
}
if (node->u()) {
node->u()->d() = node->d();
}
mesh[i].erase(mesh[i].begin() + j);
delete node;
}
Mesh::~Mesh() {
for (auto line : mesh)
for (auto node : line)
delete node;
}