xmsstamper  1.0
XmUtil.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My own header
14 
15 // 3. Standard library headers
16 #include <cmath>
17 
18 // 4. External library headers
19 
20 // 5. Shared code headers
21 #include <xmscore/misc/XmError.h>
24 
25 // 6. Non-shared code headers
26 
27 //----- Forward declarations ---------------------------------------------------
28 
29 //----- External globals -------------------------------------------------------
30 
31 //----- Namespace declaration --------------------------------------------------
32 
33 namespace xms
34 {
35 //----- Constants / Enumerations -----------------------------------------------
36 
37 //----- Classes / Structs ------------------------------------------------------
38 
39 //------------------------------------------------------------------------------
48 //------------------------------------------------------------------------------
50  const VecPt3d& a_pts,
51  double a_maxX,
52  double a_angle,
53  VecPt3d2d& a_3dpts)
54 {
55  if (a_pts.size() < 2 || a_maxX <= 0.0)
56  return;
57 
58  VecPt3d pts(a_pts);
59  XmUtil::EnsureVectorAtMaxX(pts, a_maxX);
60 
61  a_3dpts.push_back(VecPt3d());
62  VecPt3d& pts3d(a_3dpts.back());
63  Pt3d p3d;
64  for (size_t i = 1; i < pts.size(); ++i)
65  {
66  double x2d = pts[i].x;
67  double z = pts[i].y;
68  p3d.z = z;
69  p3d.x = a_cl.x + x2d * cos(a_angle);
70  p3d.y = a_cl.y + x2d * sin(a_angle);
71  // add the point
72  pts3d.push_back(p3d);
73  }
74 } // XmUtil::ConvertXsPointsTo3d
75 //------------------------------------------------------------------------------
79 //------------------------------------------------------------------------------
81 {
82  for (auto& v : a_xs.m_left)
83  v.x *= a_factor;
84  for (auto& v : a_xs.m_right)
85  v.x *= a_factor;
86  a_xs.m_leftMax *= a_factor;
87  a_xs.m_rightMax *= a_factor;
88 } // XmUtil::ScaleCrossSectionXvals
89 //------------------------------------------------------------------------------
93 //------------------------------------------------------------------------------
94 void XmUtil::EnsureVectorAtMaxX(VecPt3d& a_pts, double a_maxX)
95 {
96  if (a_pts.empty())
97  return;
98  if (a_pts.size() < 2)
99  {
100  a_pts[0].x = 0;
101  a_pts.push_back(Pt3d(a_maxX, a_pts.front().y));
102  return;
103  }
104  if (a_pts.back().x < a_maxX)
105  {
106  Pt3d p0(a_pts[a_pts.size() - 2]), p1(a_pts.back());
107  double t = (a_maxX - p0.x) / (p1.x - p0.x);
108  double z = p0.y + t * (p1.y - p0.y);
109  a_pts.back() = Pt3d(a_maxX, z);
110  return;
111  }
112 
113  if (a_pts.front().x > a_maxX)
114  {
115  VecPt3d vp(2);
116  vp[0] = Pt3d(0, a_pts.front().y);
117  vp[1] = Pt3d(a_maxX, vp[0].y);
118  a_pts.swap(vp);
119  return;
120  }
121 
122  // truncate to maxX
123  bool done(false);
124  for (size_t i = 1; !done && i < a_pts.size(); ++i)
125  {
126  if (a_pts[i].x > a_maxX)
127  {
128  Pt3d p0(a_pts[i - 1]), p1(a_pts[i]);
129  double t = (a_maxX - p0.x) / (p1.x - p0.x);
130  double z = p0.y + t * (p1.y - p0.y);
131  Pt3d p3(Pt3d(a_maxX, z));
132  a_pts.resize(i);
133  a_pts.push_back(p3);
134  done = true;
135  }
136  else if (a_pts[i].x == a_maxX)
137  {
138  a_pts.resize(i + 1);
139  done = true;
140  }
141  }
142 } // XmUtil::EnsureVectorAtMaxX
143 //------------------------------------------------------------------------------
152 //------------------------------------------------------------------------------
154  const VecPt3d& a_cl,
155  double& a_leftAngle,
156  double& a_rightAngle)
157 {
158  a_leftAngle = a_rightAngle = 0;
159  if (a_cl.size() < 2)
160  return;
161 
162  XM_ENSURE_TRUE(a_cl.size() > a_idx);
163 
164  Pt3d p(a_cl[a_idx]);
165  if (0 == a_idx)
166  {
167  Pt3d p1(a_cl[a_idx + 1]);
168  a_leftAngle = gmPerpendicularAngle(p, p1);
169  a_rightAngle = gmPerpendicularAngle(p1, p);
170  }
171  else if (a_cl.size() - 1 == a_idx)
172  {
173  Pt3d p1(a_cl[a_idx - 1]);
174  a_leftAngle = gmPerpendicularAngle(p1, p);
175  a_rightAngle = gmPerpendicularAngle(p, p1);
176  }
177  else
178  {
179  Pt3d p0(a_cl[a_idx - 1]);
180  Pt3d p1(a_cl[a_idx + 1]);
181  a_leftAngle = gmBisectingAngle(p1, p, p0);
182  a_rightAngle = gmBisectingAngle(p0, p, p1);
183  }
184 } // XmUtil::GetAnglesFromCenterLine
185 
186 } // namespace xms
187 
188 #ifdef CXX_TEST
189 //------------------------------------------------------------------------------
190 // Unit Tests
191 //------------------------------------------------------------------------------
192 using namespace xms;
194 
196 
197 //------------------------------------------------------------------------------
199 //------------------------------------------------------------------------------
201 {
202  VecPt3d pts, basePts;
203 
204  pts = {{5, 6}};
206  basePts = {{0, 6}, {3, 6}};
207  TS_ASSERT_EQUALS_VEC(basePts, pts);
208 
209  pts = {{5, 6}, {6, 7}, {7, 8}};
211  basePts = {{0, 6}, {3, 6}};
212  TS_ASSERT_EQUALS_VEC(basePts, pts);
213 
214  pts = {{5, 6}, {6, 7}, {7, 8}};
216  basePts = {{5, 6}, {6, 7}};
217  TS_ASSERT_EQUALS_VEC(basePts, pts);
218 
219  pts = {{0, 6}, {5, 6}, {15, 0}};
221  basePts = {{0, 6}, {5, 6}, {10, 3}};
222  TS_ASSERT_EQUALS_VEC(basePts, pts);
223 
224  pts = {{0, 6}, {5, 6}, {15, 0}};
226  basePts = {{0, 6}, {5, 6}, {20, -3}};
227  TS_ASSERT_EQUALS_VEC(basePts, pts);
228 } // XmUtilUnitTests::test_EnsureVectorAtMaxX
229 
230 #endif
void test_EnsureVectorAtMaxX()
Tests XmUtilUnitTests.
Definition: XmUtil.cpp:200
VecPt3d m_left
left side of the cross section
Definition: XmStamperIo.h:156
double m_leftMax
max x value for left side
Definition: XmStamperIo.h:157
static void EnsureVectorAtMaxX(VecPt3d &a_pts, double a_maxX)
Makes sure the cross section goes to the maxX value.
Definition: XmUtil.cpp:94
static void GetAnglesFromCenterLine(size_t a_idx, const VecPt3d &a_cl, double &a_leftAngle, double &a_rightAngle)
Gets the angles of the left and right cross sections relative to the centerline.
Definition: XmUtil.cpp:153
#define XM_ENSURE_TRUE(...)
double m_rightMax
max x value for right side
Definition: XmStamperIo.h:161
VecPt3d m_right
right side of the cross section
Definition: XmStamperIo.h:160
static void ConvertXsPointsTo3d(const Pt3d &a_cl, const VecPt3d &a_pts, double a_maxX, double a_angle, VecPt3d2d &a_3dpts)
Converts the left or right portion of a cross section data to 3d point locations using the angle from...
Definition: XmUtil.cpp:49
std::vector< VecPt3d > VecPt3d2d
Cross section definition for stamping.
Definition: XmStamperIo.h:142
#define TS_ASSERT_EQUALS_VEC(a, b)
double gmPerpendicularAngle(const Pt3d &a_pt1, const Pt3d &a_pt2)
double gmBisectingAngle(const Pt3d &a_p1, const Pt3d &a_p2, const Pt3d &a_p3)
std::vector< Pt3d > VecPt3d
static void ScaleCrossSectionXvals(XmStampCrossSection &a_xs, double a_factor)
Converts interpolated cross sections to 3d.
Definition: XmUtil.cpp:80