Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ target_link_libraries(hexgrid mathplot_examples)
add_executable(hexgrid_transforms hexgrid_transforms.cpp)
target_link_libraries(hexgrid_transforms mathplot_examples)

add_executable(hexgrid_boundary hexgrid_boundary.cpp)
target_link_libraries(hexgrid_boundary mathplot_examples)

add_executable(hexgrid_fft hexgrid_fft.cpp)
target_link_libraries(hexgrid_fft mathplot_examples)

Expand Down
52 changes: 52 additions & 0 deletions examples/hexgrid_boundary.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* An example mplot::Visual scene, containing hexgrid with boundary shown
*/

#include <iostream>
#include <memory>
#include <vector>
#include <cmath>

import sm.vec;
import sm.hexgrid;

import mplot.visual;
import mplot.visualdatamodel;
import mplot.hexgridvisual;

int main()
{
// Contructor args are width, height, title
mplot::Visual<mplot::gl::version_4_1> v(1600, 1000, "mplot::HexGridVisual");
v.fov = 15;
//v.rotateAboutNearest (true);

sm::hexgrid<float, sm::hexalign::point_up> hg1(0.01f, 0.205f, 0.0f);
hg1.set_circular_boundary (0.1f);
//hg1.set_boundary_on_outer_edge();

// Make some dummy data (a sine wave) to make an interesting surface
std::vector<float> data1(hg1.num(), 0.0f);
for (unsigned int ri = 0; ri < hg1.num(); ++ri) {
data1[ri] = 0.05f + 0.05f * std::sin (20.0f * hg1.d_x[ri]) * std::sin (10.0f * hg1.d_y[ri]) ; // Range 0->1
}

// sm::HexVisMode::HexInterp to see the hexagons or sm::HexVisMode::Triangles for a smoother surface plot
const mplot::HexVisMode visMode = mplot::HexVisMode::HexInterp;

sm::vec<float, 3> offset = { 0.0f, -0.05f, 0.0f };
auto hgv1 = std::make_unique<mplot::HexGridVisual<float, sm::hexalign::point_up, mplot::gl::version_4_1>>(&hg1, offset);
hgv1->set_parent (v.get_id());
hgv1->cm.setType (mplot::ColourMapType::Ice);
hgv1->showboundary = true;
hgv1->setScalarData (&data1);
hgv1->hexVisMode = visMode;
hgv1->zScale.null_scaling();
hgv1->addLabel ("hexalign::point_up", sm::vec<>{ -hg1.width()/2.1f, -hg1.width()/1.6f }, mplot::TextFeatures(0.02f));
hgv1->finalize();
v.addVisualModel (hgv1);

v.keepOpen();

return 0;
}
2 changes: 1 addition & 1 deletion maths
59 changes: 59 additions & 0 deletions mplot/HexGridVisual.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,70 @@ export namespace mplot
if (this->showhexes == true) {
this->computeHexes();
}
// Boundary
if (this->showboundary == true) {
this->computeHexgridBoundary();
}
// Optionally show a Flat surface for the zero plane
if (this->zerogrid == true) {
this->computeZerogridIndices();
}
// End trial grid
}

// Draw carefully around the boundary with tubes or lines or quads
void computeHexgridBoundary()
{
constexpr std::array<float, 3> clr = {};
constexpr std::array<float, 3> clr0 = {.1f,.1f,.1f};
sm::mat<float, 3> lt (this->hg->tfm.template as<float>());
//std::cout << "lt:\n" << lt << std::endl;

for (auto hptr : this->hg->bhexen) {
std::uint32_t hi = hptr->vi;
// Look at each possible neighbour direction and see if we need a tube
for (std::uint32_t i = 0; i < 6; ++i) {
if (this->hg->has_neighbour (hi, i) == false) {
// There's no neighbour, so we need a tube. The logic is made complex by the
// need to angle the ends of the tubes correctly depending on the shape of
// the boundary
std::uint32_t i0 = (i + 5u) % 6u;
sm::vec<float, 3> c0 = lt * hptr->get_vertex_coord (i0).template as<float>().plus_one_dim (0.0f);
sm::vec<float, 3> c = lt * hptr->get_vertex_coord (i).template as<float>().plus_one_dim (0.0f);

sm::vec<float, 3> u0 = {}; // tube end normal for c0
sm::vec<float, 3> u = {}; // tube end normal for c
sm::vec<float> v = {};

std::uint32_t di = 0u; // direction to corner neighbour
std::uint32_t vi = 0u; // vector to cross with uz depends on if corner neighbour exists or not

di = (i + 5u) % 6u;
if (this->hg->has_neighbour (hi, di) == false) {
vi = (i + 5u) % 6u;
} else {
vi = i;
}
v = hptr->get_vertex (vi).template as<float>().plus_one_dim();
v.renormalize();
u0 = lt * v.cross (sm::vec<float>::uz());

di = (i + 1u) % 6u;
if (this->hg->has_neighbour (hi, di) == false) {
vi = i;
} else {
vi = (i + 5u) % 6u;
}
v = hptr->get_vertex (vi).template as<float>().plus_one_dim();
v.renormalize();
u = lt * v.cross (-sm::vec<float>::uz());

this->computeOpenFlaredTube (c0, c, u0, u, clr0, clr, this->hg->d / 12.0f, this->hg->d / 12.0f);
}
}
}
}

// Compute vertices for the patchwork quilt of hexes
void computeHexes()
{
Expand Down Expand Up @@ -407,9 +464,11 @@ export namespace mplot
// Use a single colour for each hex, even though hex z positions are
// interpolated. Do the _colour_ scaling:
std::array<float, 3> clr = this->setColour (hi);
#if 0 // Now going to draw carefully around the boundary
if (this->showboundary && (this->hg->vhexen[hi])->boundary_hex() == true) {
this->markHex (hi);
}
#endif
if (this->showcentre && _x == 0.0f && _y == 0.0f) {
this->markHex (hi);
}
Expand Down
Loading