NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
HexagonalArray.C
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #include "NucMesh/HexagonalArray.H"
30 
31 #define _USE_MATH_DEFINES
32 #include <cmath>
33 
34 #include <gp_Trsf.hxx>
35 #include <gp_Vec.hxx>
36 
37 namespace NEM {
38 namespace NUCMESH {
39 
40 namespace {
41 
42 std::size_t coordsToSpiralFlat(int right, int rightUp) {
43  /*
44  * This converts (right, rightUp) coordinates to a flattened spiral.
45  *
46  * The value returned is the number of coordinates "dealt with" once
47  * that coordinate has been reached, if you start at the center and
48  * spiral outwards counterclockwise.
49  */
50  int ring; // 0-indexed ring number, counting from the center
51  int corner; // reference corner from which offset is figured
52  int offset; // how far into a side you've gone
53  if (right >= 0) {
54  if (rightUp >= 0) {
55  corner = 0; // start at corner 0 (center-right)
56  ring = right + rightUp;
57  offset = rightUp; // count upwards
58  if (ring == 0) offset = -1; // special case for middle point
59  } else if (right <= -rightUp) {
60  corner = 4; // start at corner 4 (bottom-left)
61  ring = -rightUp;
62  offset = right; //count rightwards
63  } else {
64  corner = 0; // start at corner 0 (center-right)
65  ring = right + 1;
66  offset = rightUp; // count downwards
67  }
68  } else {
69  if (rightUp <= 0) {
70  corner = 3; // start from corner 3 (center-left)
71  ring = -(right + rightUp);
72  offset = -rightUp; // count (negative) downward
73  } else if (-right <= rightUp) {
74  corner = 1; // start from corner 1 (top-right)
75  ring = rightUp;
76  offset = -right; // count (negative) rightwards
77  } else {
78  corner = 3; // start from corner 3 (center-left)
79  ring = -right;
80  offset = -rightUp; // count (negative) downward
81  }
82  }
83  // note that 3*N(N-1)+1 is the Nth hexagonal number
84  return 3 * ring * (ring - 1) + 1 + corner * ring + offset;
85 }
86 
87 void incrementSpiral(int &right, int &rightUp, int &side) {
88  switch (side) {
89  case 0: {
90  --right;
91  ++rightUp;
92  if (right == 0) ++side;
93  break;
94  }
95  case 1: {
96  --right;
97  if (right == -rightUp) ++side;
98  break;
99  }
100  case 2: {
101  --rightUp;
102  if (rightUp == 0) ++side;
103  break;
104  }
105  case 3: {
106  ++right;
107  --rightUp;
108  if (right == 0) ++side;
109  break;
110  }
111  case 4: {
112  ++right;
113  if (right == -rightUp) ++side;
114  break;
115  }
116  case 5: {
117  if (rightUp >= -1) {
118  side = 0;
119  ++right;
120  rightUp = 0;
121  } else {
122  ++rightUp;
123  }
124  break;
125  }
126  default: break;
127  }
128 }
129 
130 std::array<int, 2> rowColToCoords(int row, int col, std::size_t width) {
131  int iwidth = static_cast<int>(width);
132  if (row <= iwidth - 1) {
133  return {col - iwidth + 1, iwidth - row - 1};
134  } else {
135  return {row + col - 2 * (iwidth - 1), iwidth - row - 1};
136  }
137 }
138 
139 } // namespace
140 
141 HexagonalArray::HexagonalArray(std::size_t numRadii, double deltaRadius,
142  const std::array<double, 3> &center)
143  : ShapesArray(center, 3 * (numRadii) * (numRadii - 1) + 1),
144  delta_(deltaRadius),
145  numRadii_(numRadii) {}
146 
147 const std::size_t &HexagonalArray::getPatternRowCol(int row, int col) const {
148  auto coords = rowColToCoords(row, col, numRadii_);
149  return getPatternCoordCenter(coords[0], coords[1]);
150 }
151 
152 const std::size_t &HexagonalArray::getPatternCoordCenter(int right,
153  int rightUp) const {
154  return this->getPattern(coordsToSpiralFlat(right, rightUp));
155 }
156 
157 void HexagonalArray::setPatternRowCol(int row, int col,
158  std::size_t patternKey) {
159  auto coords = rowColToCoords(row, col, numRadii_);
160  setPatternCoordCenter(coords[0], coords[1], patternKey);
161 }
162 
163 void HexagonalArray::setPatternCoordCenter(int right, int rightUp,
164  std::size_t patternKey) {
165  this->setPattern(coordsToSpiralFlat(right, rightUp), patternKey);
166 }
167 
168 // Internal representation of pattern: flattened with all shapes from ring i
169 // followed by ring i + 1, etc, with shapes in each ring represented
170 // counterclockwise from positive x-axis
172  int right = 0;
173  int rightUp = 0;
174  int side = 5;
175  return this->createGeoImpl([this, &right, &rightUp,
176  &side](NEM::GEO::GeoManager *const inp) {
177  if (inp) {
178  const auto &center = this->getCenter();
179  const gp_Vec dest{
180  center[0] + delta_ * (right + rightUp * std::cos(60 * M_PI / 180.)),
181  center[1] + rightUp * delta_ * std::sin(60 * M_PI / 180.), center[2]};
182  gp_Trsf translation{};
183  translation.SetTranslation(dest);
184  *inp = ShapesArray::basicTransformation(translation, std::move(*inp));
185  }
186  incrementSpiral(right, rightUp, side);
187  });
188 }
189 
190 } // namespace NUCMESH
191 } // namespace NEM
Class to manage TopoDS_Shapes along with metadata.
Definition: GeoManager.H:61
void setPatternRowCol(int row, int col, std::size_t patternKey)
void setPatternCoordCenter(int right, int rightUp, std::size_t patternKey)
The shape will be translated by right * [getGridDistance(), 0, 0] + rightUp * [getGridDistance() * c...
NEM::GEO::GeoManager createGeo() const override
Construct a NEM::GEO::GeoManager.
HexagonalArray(std::size_t numRadii, double deltaRadius, const std::array< double, 3 > &center={0, 0, 0})
const std::array< double, 3 > & getCenter() const
Definition: ShapeBase.C:50
const std::size_t & getPatternRowCol(int row, int col) const
NEM::GEO::GeoManager createGeoImpl(Modifier &&modifier) const
Definition: ShapesArray.H:87
const std::size_t & getPatternCoordCenter(int right, int rightUp) const
static NEM::GEO::GeoManager basicTransformation(const gp_Trsf &transformation, NEM::GEO::GeoManager &&geoMetadata)
Definition: ShapesArray.C:81
Abstract base class representing a set of other ShapeBase objects, with a transformation applied to e...
Definition: ShapesArray.H:52
void setPattern(std::size_t idx, std::size_t patternKey)
Definition: ShapesArray.C:77
const std::size_t & getPattern(std::size_t idx) const
Definition: ShapesArray.C:73