NAP
lineutils.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 // Local Includes
8 #include "mathutils.h"
9 
10 // External Includes
11 #include <vector>
12 #include <unordered_map>
13 #include <map>
14 
15 namespace nap
16 {
17  namespace math
18  {
28  template<typename T>
29  void getValueAlongLine(const std::vector<T>& vertexData, float location, bool closed, T& outValue);
30 
41  template<typename T>
42  int resampleLine(std::vector<T>& vertices, std::vector<T>& buffer, int segments, bool closed);
43 
53  float NAPAPI getDistancesAlongLine(const std::vector<glm::vec3>& vertexPositions, std::map<float, int>& outDistances, bool loop);
54 
63  float NAPAPI getVertexLerpValue(const std::map<float, int>& distanceMap, float location, int& outMinVertex, int& outMaxVertex);
64 
73  template<typename T>
74  void getValueAlongLine(const std::map<float, int>& distanceMap, const std::vector<T>& vertexData, float location, T& outValue);
75 
85  void NAPAPI getNormalAlongLine(const std::map<float, int>& distanceMap, const std::vector<glm::vec3>& vertexNormals, float location, glm::vec3& outNormal);
86 
87 
89  // Template definitions
91 
92  template<typename T>
93  void getValueAlongLine(const std::vector<T>& vertexData, float location, bool closed, T& outValue)
94  {
95  // Get vertex range, when the line is closed it means that we want to
96  // include the first vertex as last
97  int vert_count = static_cast<int>(vertexData.size());
98  assert(vert_count > 0);
99  int range = closed ? vert_count : vert_count - 1;
100 
101  // Get interpolation location
102  float loc = location * static_cast<float>(range);
103 
104  // Get min and max point bounds, wrap the last vertex if the line is closed
105  // ie: the last vertex is the first vertex
106  int min_vertex = static_cast<int>(math::floor<float>(loc));
107  int max_vertex = static_cast<int>(math::ceil<float>(loc));
108 
109  min_vertex = min_vertex % vert_count;
110  max_vertex = max_vertex % vert_count;
111 
112  // Get lerp value that sits in between min / max
113  float lerp_v = loc - static_cast<float>(static_cast<int>(loc));
114 
115  // Ensure points are in bounds
116  assert(min_vertex <= vert_count - 1);
117  assert(max_vertex <= vert_count - 1);
118 
119  // Lerp between min and max value
120  const T& min_p_value = vertexData[min_vertex];
121  const T& max_p_value = vertexData[max_vertex];
122 
123  outValue = math::lerp<T>(min_p_value, max_p_value, lerp_v);
124  }
125 
126 
127  template<typename T>
128  int resampleLine(std::vector<T>& vertices, std::vector<T>& buffer, int segments, bool closed)
129  {
130  assert(segments > 0);
131  int vertex_count = static_cast<int>(vertices.size());
132 
133  // If there not enough or an equal amount or less vertices, don't do anything
134  if (segments <= vertex_count || vertex_count < 2)
135  {
136  buffer = vertices;
137  return vertices.size();
138  }
139 
140  // Figure out the amount of edges, closed lines have one extra edge (connecting first to last)
141  int edge_count = closed ? vertex_count : vertex_count - 1;
142 
143  // Calculate the total amount of pointer for every side
144  int pps = segments / edge_count;
145 
146  // Clear existing buffer data
147  buffer.clear();
148 
149  // Reserve space for points to add
150  buffer.reserve(segments);
151 
152  for (int i = 0; i < edge_count; i++)
153  {
154  // Get edge points
155  T& point_one = vertices[i];
156  T& point_two = i + 1 >= vertex_count ? vertices[0] : vertices[i + 1];
157 
158  // Add edge vertices
159  for (int p = 0; p < pps; p++)
160  {
161  float inc = static_cast<float>(p) / static_cast<float>(pps);
162  buffer.emplace_back(nap::math::lerp<T>(point_one, point_two, inc));
163  }
164  }
165 
166  // If the line is open add an additional point
167  if (!closed)
168  {
169  buffer.emplace_back(vertices.back());
170  }
171 
172  // Return total number of new points
173  return buffer.size();
174  }
175 
176 
177  template<typename T>
178  void getValueAlongLine(const std::map<float, int>& distances, const std::vector<T>& vertexData, float location, T& outValue)
179  {
180  int vert_min, vert_max;
181  float lerp_v = getVertexLerpValue(distances, location, vert_min, vert_max);
182 
183  // Get the values to interpolate
184  const T& lower_value = vertexData[vert_min];
185  const T& upper_value = vertexData[vert_max];
186 
187  outValue = math::lerp<T>(lower_value, upper_value, lerp_v);
188  }
189  }
190 }
nap::math::resampleLine
int resampleLine(std::vector< T > &vertices, std::vector< T > &buffer, int segments, bool closed)
Definition: lineutils.h:128
nap::math::getVertexLerpValue
float NAPAPI getVertexLerpValue(const std::map< float, int > &distanceMap, float location, int &outMinVertex, int &outMaxVertex)
nap::math::getNormalAlongLine
void NAPAPI getNormalAlongLine(const std::map< float, int > &distanceMap, const std::vector< glm::vec3 > &vertexNormals, float location, glm::vec3 &outNormal)
nap
Definition: templateapp.h:17
nap::math::getDistancesAlongLine
float NAPAPI getDistancesAlongLine(const std::vector< glm::vec3 > &vertexPositions, std::map< float, int > &outDistances, bool loop)
nap::math::getValueAlongLine
void getValueAlongLine(const std::vector< T > &vertexData, float location, bool closed, T &outValue)
Definition: lineutils.h:93