hyporo-cpp/source/applications/periodic/periodic.cpp

246 lines
6.0 KiB
C++
Raw Normal View History

2022-11-18 21:50:49 +05:00
#include "../../hyporo/hyplib/scalar/scalar.hpp"
#include "../../hyporo/hyplib/vector/vector.hpp"
#include "../../hyporo/hyplib/array/array.hpp"
#include "../../hyporo/csg/csg.hpp"
#include <iostream>
#include <map>
using namespace hpr;
void print(vec3 vs)
{
for (auto& v : vs)
std::cout << v << " ";
std::cout << std::endl;
}
class Periodic
{
protected:
scalar p_alpha;
scalar p_initialRadius;
scalar p_sideLength;
scalar p_filletScale;
vec3 p_direction;
public:
Periodic() :
p_alpha {0.1},
p_initialRadius {1},
p_filletScale {0.8},
p_direction {}
{}
Periodic(scalar alpha, scalar initialRadius, scalar filletScale, const vec3& direction) :
p_alpha {alpha},
p_initialRadius {initialRadius},
p_filletScale {filletScale},
p_direction {direction}
{}
virtual
~Periodic() = default;
scalar& alpha()
{
return p_alpha;
}
scalar& initialRadius()
{
return p_initialRadius;
}
virtual
scalar sideLength() = 0;
virtual
scalar gamma() = 0;
scalar& filletScale()
{
return p_filletScale;
}
scalar radius() const
{
return p_initialRadius / (1. - p_alpha);
}
scalar filletRadius()
{
scalar analytical = p_initialRadius * sqrt(2) / sqrt(1 - cos(gamma())) - radius();
return analytical * p_filletScale;
}
vec3& direction()
{
return p_direction;
}
virtual
void build() = 0;
};
class Simple : public Periodic, public csg::Shape
{
public:
Simple() :
csg::Shape {},
Periodic {0.01, 1, 0.8, vec3(1., 0., 0.)}
{}
Simple(scalar alpha, const vec3& direction, scalar filletScale = 0.8) :
Simple {}
{
p_alpha = alpha;
p_direction = direction;
p_filletScale = filletScale;
}
Simple(scalar alpha, scalar initialRadius, scalar filletScale, const vec3& direction) :
Periodic {alpha, initialRadius, filletScale, direction}
{}
~Simple() override = default;
scalar sideLength() override
{
return 2 * initialRadius();
}
scalar gamma() override
{
return hpr::PI - 2 * 0.5 * 0.5 * hpr::PI;
}
csg::Shape lattice()
{
csg::Shape lattice;
darray<csg::Shape> spheres;
for (int zn = 0; zn < 3; ++zn)
{
scalar z = zn * sideLength();
for (int yn = 0; yn < 3; ++yn)
{
scalar y = yn * sideLength();
for (int xn = 0; xn < 3; ++xn)
{
scalar x = xn * sideLength();
spheres.push(csg::sphere(vec3(x, y, z), radius()));
}
}
}
lattice = csg::fuse({spheres.front()}, spheres.slice(spheres.begin() + 1, spheres.end()));
if (filletScale() > 0)
{
lattice = lattice.scale({0, 0, 0}, 1e+2);
lattice = lattice.fillet(lattice.edges(), filletRadius() * 1e+2);
lattice = lattice.scale({0, 0, 0}, 1e-2);
}
2022-12-06 23:52:49 +05:00
std::cout << (int)lattice.type() << std::endl;
2022-11-18 21:50:49 +05:00
return lattice;
}
csg::Shape boxCell()
{
scalar length = sideLength() * sqrt(2);
scalar width = sideLength() * sqrt(2);
scalar height = sideLength();
scalar xl = sqrt(pow(length, 2) * 0.5);
scalar yw = xl;
scalar zh = height;
darray<Shape> edges {
csg::Edge({xl, 0, 0}, {0, yw, 0}),
csg::Edge({0, yw, 0}, {0, yw, zh}),
csg::Edge({0, yw, zh}, {xl, 0, zh}),
csg::Edge({xl, 0, zh}, {xl, 0, 0})
};
csg::Face plgm {edges};
vec3 localX {csg::Surface(plgm).normal(0, 0)};
vec3 localZ = vec3(0, 0, 1);
vec3 localY = cross(localX, localZ);
csg::Shape cell = plgm.extrude(localX, width);
scalar angle;
hpr::vec3 normal;
for (auto& face : cell.faces())
{
normal = csg::Surface(csg::Face(face)).normal(0, 0);
angle = hpr::angle(localX, normal);
if (face.tshape().Orientation() == TopAbs_FORWARD)
{
normal = -normal;
angle = hpr::angle(localX, normal);
}
if (equal(angle, 0.))
face.label("periodic-south");
else if (equal(angle, hpr::PI))
face.label("periodic-north");
angle = hpr::angle(localY, normal);
if (equal(angle, 0.))
face.label("periodic-east");
else if (equal(angle, hpr::PI))
face.label("periodic-west");
angle = hpr::angle(localZ, normal);
if (equal(angle, hpr::PI))
face.label("periodic-down");
else if (equal(angle, 0.))
face.label("periodic-up");
}
2022-12-06 23:52:49 +05:00
std::cout << (int)cell.type() << std::endl;
2022-11-18 21:50:49 +05:00
return cell;
}
csg::Shape hexagonalPrismCell()
{
return csg::Shape();
}
void build() override
{
if (direction() == vec3(1., 0., 0.) || direction() == vec3(1., 0., 0.) || direction() == vec3(0., 0., 1.))
p_shape = csg::cut(boxCell(), lattice()).tshape();
else if (direction() == vec3(1., 1., 1.))
p_shape = csg::cut(hexagonalPrismCell(), lattice()).tshape();
else
throw std::runtime_error("Undefined cell for passed direction");
p_shape = this->translate(-this->center()).tshape();
p_shape = this->rotate(this->center(), {0, 0, 1}, 45).tshape();
for (auto& face : faces())
if (face.label() == "default")
face.label("wall");
}
};
2022-12-06 23:52:49 +05:00
#include "lattice.hpp"
2022-11-18 21:50:49 +05:00
int main(int argc, char** argv)
{
2022-12-06 23:52:49 +05:00
/*Simple simple {0.01, {1., 0., 0.}};
2022-11-18 21:50:49 +05:00
simple.build();
2022-12-06 23:52:49 +05:00
std::cout << (int)simple.type() << std::endl;
std::cout << simple.volume() << std::endl;
*/
csg::Lattice lattice {{2, 2, 2}, {90, 90, 90}, 1, csg::Lattice::Type::Primitive};
lattice.dump("latticeTest.step", csg::Shape::Format::STEP);
2022-11-18 21:50:49 +05:00
return 0;
}