Skip to content

Commit

Permalink
Files missing from commit
Browse files Browse the repository at this point in the history
  • Loading branch information
TrentHouliston committed Jul 16, 2019
1 parent d9640bf commit 57ba7c2
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 59 deletions.
53 changes: 10 additions & 43 deletions src/mesh/mesh.hpp
Expand Up @@ -61,55 +61,23 @@ template <typename Scalar>
struct Mesh {

template <typename Shape>
Mesh(const Shape& shape, const Scalar& h) {
Mesh(const Shape& shape, const Scalar& h, const Scalar& k, const Scalar& max_distance) : h(h) {

// This is a list of phi values along with the delta theta values associated with them
std::vector<std::pair<Scalar, int>> phis;

// Add our 0 point at the bottom if that is a valid location
if (shape.phi(Scalar(0.0), h) < Scalar(M_PI_2)) { phis.emplace_back(Scalar(0.0), 1); }
const Scalar jump = 1.0 / k;
for (Scalar n = 0; phis.empty() || h * std::tan(phis.back().first) < max_distance; n += jump) {

// Loop from directly down up to the horizon (if phi is nan it will stop)
// So we don't have a single point at the base, we move half a jump forward
// The final step is when phi is >= M_PI_2 or NaN, both of which compare false here
for (Scalar phi = shape.phi(Scalar(0.0), h); phi < Scalar(M_PI_2);) {

// Calculate our theta
// Calculate phi and theta for this shape and calculate how many slices ensures we have at least enough
Scalar phi = shape.phi(n, h);
Scalar theta = shape.theta(phi, h);
int slices = static_cast<int>(std::ceil(k * 2 * M_PI / theta));

// We don't add NaN thetas
if (!std::isnan(theta)) {
// Push back the phi, and the number of whole shapes we can fit
phis.emplace_back(phi, static_cast<unsigned int>(std::ceil(Scalar(2.0) * M_PI / theta)));
}

// Calculate our next phi value
phi = shape.phi(phi, h);
// Push back this new slice
if (!std::isnan(theta)) { phis.emplace_back(phi, slices); }
}

// Add our 0 point at the bottom if that is a valid location
if (Scalar(M_PI) + shape.phi(M_PI, h) > Scalar(M_PI_2)) { phis.emplace_back(Scalar(M_PI), 1); }

// Loop from directly up down to the horizon
// The final step is when phi is <= M_PI_2 or NaN, both of which compare false here
for (Scalar phi = shape.phi(M_PI, h); phi > Scalar(M_PI_2);) {

// Calculate our theta
Scalar theta = shape.theta(phi, h);

// Don't push ban NaN thetas
if (!std::isnan(theta)) {
// Push back the phi, and the number of whole shapes we can fit
phis.emplace_back(phi, static_cast<unsigned int>(std::ceil(Scalar(2.0) * M_PI / theta)));
}

// Calculate our next phi value
phi = shape.phi(phi, h);
}

// Sort the list by phi to create a contiguous area
std::sort(phis.begin(), phis.end());

// Work out how big our LUT will be
unsigned int lut_size = 0;
for (const auto& v : phis) {
Expand All @@ -122,7 +90,6 @@ struct Mesh {

// Loop through our LUT and calculate our left and right neighbours
for (const auto& v : phis) {

// Get our phi and delta theta values for a clean circle
const auto& phi = v.first;
const Scalar sin_phi = std::sin(phi);
Expand Down Expand Up @@ -213,7 +180,6 @@ struct Mesh {

// Now we iterate upwards and downwards to fill in the missing links
for (unsigned int r = 1; r + 1 < rows.size(); ++r) {

// Alias for convenience
const auto& prev = rows[r - 1];
const auto& current = rows[r];
Expand Down Expand Up @@ -652,7 +618,8 @@ struct Mesh {
default: { throw std::runtime_error("Unknown lens type"); }
}
}

/// The height that this mesh is designed to run at
Scalar h;
/// The lookup table for this mesh
std::vector<Node<Scalar>> nodes;
/// A set of individual rows for phi values.
Expand Down
105 changes: 89 additions & 16 deletions src/util/math.hpp
Expand Up @@ -18,7 +18,6 @@
#ifndef VISUALMESH_UTILITY_MATH_HPP
#define VISUALMESH_UTILITY_MATH_HPP

#include <algorithm>
#include <array>
#include <cmath>

Expand All @@ -36,51 +35,125 @@ using mat3 = std::array<vec3<Scalar>, 3>;
template <typename Scalar>
using mat4 = std::array<vec4<Scalar>, 4>;

/**
* Dot product
*/
template <typename T, std::size_t I>
struct Dot;

template <typename Scalar, std::size_t L>
struct Dot<std::array<Scalar, L>, 0> {
static Scalar dot(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
static inline Scalar dot(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
return a[0] * b[0];
}
};

template <typename Scalar, std::size_t L, std::size_t I>
struct Dot<std::array<Scalar, L>, I> {
static Scalar dot(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
static inline Scalar dot(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
return a[I] * b[I] + Dot<std::array<Scalar, L>, I - 1>::dot(a, b);
}
};

template <typename Scalar, std::size_t L>
Scalar dot(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
inline Scalar dot(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
return Dot<std::array<Scalar, L>, L - 1>::dot(a, b);
}

/**
* Vector norm
*/
template <typename Scalar, std::size_t L>
inline Scalar norm(const std::array<Scalar, L>& a) {
return std::sqrt(dot(a, a));
}

/**
* Vector normalise
*/
template <typename Scalar, std::size_t L>
inline std::array<Scalar, L> normalise(const std::array<Scalar, L>& a) {
const Scalar len = static_cast<Scalar>(1.0) / norm(a);
return multiply(a, len);
}

/**
* Vector subtraction
*/
template <typename Scalar, std::size_t L, std::size_t... I>
inline std::array<Scalar, L> subtract(const std::array<Scalar, L>& a,
const std::array<Scalar, L>& b,
const std::index_sequence<I...>&) {
return {(a[I] - b[I])...};
}

template <typename Scalar, std::size_t L>
inline std::array<Scalar, L> subtract(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
return subtract(a, b, std::make_index_sequence<L>());
}

/**
* Vector addition
*/
template <typename Scalar, std::size_t L, std::size_t... I>
inline std::array<Scalar, L> add(const std::array<Scalar, L>& a,
const std::array<Scalar, L>& b,
const std::index_sequence<I...>&) {
return {(a[I] + b[I])...};
}

template <typename Scalar, std::size_t L>
inline std::array<Scalar, L> add(const std::array<Scalar, L>& a, const std::array<Scalar, L>& b) {
return add(a, b, std::make_index_sequence<L>());
}

/**
* Vector multiply by scalar
*/
template <typename Scalar, std::size_t L, std::size_t... I>
inline std::array<Scalar, L> multiply(const std::array<Scalar, L>& a,
const Scalar& s,
const std::index_sequence<I...>&) {
return {{(a[I] * s)...}};
}

template <typename Scalar, std::size_t L>
inline std::array<Scalar, L> multiply(const std::array<Scalar, L>& a, const Scalar& s) {
return multiply(a, s, std::make_index_sequence<L>());
}

/**
* Vector cross product
*/
template <typename Scalar>
inline constexpr vec3<Scalar> cross(const vec3<Scalar>& a, const vec3<Scalar>& b) {
inline vec3<Scalar> cross(const vec3<Scalar>& a, const vec3<Scalar>& b) {
return {{
a[1] * b[2] - a[2] * b[1], // x
a[2] * b[0] - a[0] * b[2], // y
a[0] * b[1] - a[1] * b[0] // z
}};
}

template <typename Scalar>
inline constexpr mat4<Scalar> transpose(const mat4<Scalar> mat) {
return mat4<Scalar>{{vec4<Scalar>{{mat[0][0], mat[1][0], mat[2][0], mat[3][0]}},
vec4<Scalar>{{mat[0][1], mat[1][1], mat[2][1], mat[3][1]}},
vec4<Scalar>{{mat[0][2], mat[1][2], mat[2][2], mat[3][2]}},
vec4<Scalar>{{mat[0][3], mat[1][3], mat[2][3], mat[3][3]}}}};
/**
* Matrix transpose
*/
template <std::size_t X, typename Scalar, std::size_t L, std::size_t M, std::size_t... Y>
inline std::array<Scalar, M> transpose_vector(const std::array<std::array<Scalar, L>, M>& mat,
const std::index_sequence<Y...>&) {
return {{mat[Y][X]...}};
}

template <typename Scalar, std::size_t L>
inline constexpr std::array<Scalar, L> normalise(std::array<Scalar, L> a) {
const Scalar len = static_cast<Scalar>(1.0) / std::sqrt(dot(a, a));
std::transform(a.begin(), a.end(), [len](const Scalar& s) { return s * len; });
return a;
template <typename Scalar, std::size_t L, std::size_t M, std::size_t... X>
inline std::array<std::array<Scalar, L>, L> transpose(const std::array<std::array<Scalar, L>, M>& mat,
const std::index_sequence<X...>&) {
return {{transpose_vector<X>(mat, std::make_index_sequence<M>())...}};
}

template <typename Scalar, std::size_t L, std::size_t M>
inline std::array<std::array<Scalar, M>, L> transpose(const std::array<std::array<Scalar, L>, M>& mat) {
return transpose(mat, std::make_index_sequence<L>());
}

} // namespace visualmesh

#endif // VISUALMESH_UTILITY_MATH_HPP

0 comments on commit 57ba7c2

Please sign in to comment.