optionally pass a vector to fill with circle points

This commit is contained in:
frank 2021-08-07 01:05:16 -04:00
parent 2831f2fc60
commit fe3e0bf27f
2 changed files with 41 additions and 19 deletions

View File

@ -7,28 +7,33 @@ void sfw::set_magnitude(glm::vec2& vector, float magnitude)
}
/* Return coordinates of a point x, y at specified angle on a circle described by center and radius */
glm::vec2 sfw::get_point_on_circle(const glm::vec2& center, float radius, float angle)
glm::vec2 sfw::point_on_circle(const glm::vec2& center, float radius, float angle)
{
return {center.x + std::sin(angle) * radius, center.y - std::cos(angle) * radius};
}
/* Return a point x, y at specified angle on a circle at the origin with specified radius (default 1) */
glm::vec2 sfw::get_point_on_circle(float angle, float radius)
glm::vec2 sfw::point_on_circle(float angle, float radius)
{
return get_point_on_circle({0, 0}, radius, angle);
return point_on_circle({0, 0}, radius, angle);
}
/* Return a vector of count number of points evenly spaced around a circle starting at the angle offset
* (defaults to 0) */
std::vector<glm::vec2> sfw::get_points_on_circle(int count, float radius, const glm::vec2& center, float offset)
/* Fill a pre-initialized vector with points evenly spaced around a circle starting at the angle offset (defaults to 0) */
void sfw::points_on_circle(std::vector<glm::vec2>& points, int count, float radius, const glm::vec2& center, float offset)
{
std::vector<glm::vec2> points;
points.reserve(count);
float step = glm::two_pi<float>() / count;
for (int ii = 0; ii < count; ii++)
{
points.push_back(get_point_on_circle(center, radius, ii * step + offset));
points.push_back(point_on_circle(center, radius, ii * step + offset));
}
}
/* Return a vector of count number of points evenly spaced around a circle starting at the angle offset (defaults to 0) */
std::vector<glm::vec2> sfw::points_on_circle(int count, float radius, const glm::vec2& center, float offset)
{
std::vector<glm::vec2> points;
points.reserve(count);
points_on_circle(points, count, radius, center, offset);
return points;
}

View File

@ -36,9 +36,10 @@ namespace sfw
enum scaler {scale2x, xbr};
void set_magnitude(glm::vec2&, float);
glm::vec2 get_point_on_circle(const glm::vec2&, float, float);
glm::vec2 get_point_on_circle(float, float = 1.0f);
std::vector<glm::vec2> get_points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
glm::vec2 point_on_circle(const glm::vec2&, float, float);
glm::vec2 point_on_circle(float, float = 1.0f);
void points_on_circle(std::vector<glm::vec2>&, int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
std::vector<glm::vec2> points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f);
Box get_texture_box(SDL_Texture*);
glm::vec2 fit_and_preserve_aspect(const glm::vec2&, const glm::vec2&);
std::vector<std::vector<Box>> get_blinds_boxes(glm::vec2, float = 0.05f, int = 4);
@ -69,6 +70,7 @@ namespace sfw
void print_error(const std::string&);
void print_sdl_error(const std::string&);
/* Returns an unsorted vector of keys from the passed map */
template<typename Key, typename Value, template <typename...> class Map>
std::vector<Key> get_keys(const Map<Key, Value>& map)
{
@ -81,18 +83,21 @@ namespace sfw
return keys;
}
/* Returns true if member is found in container, false otherwise */
template<typename T1, typename T2>
bool is_in_container(T1& container, T2& member)
{
return std::find(container.begin(), container.end(), member) != container.end();
}
/* Modulus that handles negative and float arguments */
template<typename N>
inline float mod(N a, N b)
{
return (b + (a % b)) % b;
}
/* Front pad passed end string with fill character until it is width characters long and return a new string */
template<typename T>
std::string pad(T end, int width, char fill = '0')
{
@ -103,8 +108,10 @@ namespace sfw
return padded.str();
}
/* Return a vector of values in order from start to stop with step between each value, not including the stop value.
* Returns a vector of the same type as step. */
template <typename N, typename N2 = N>
std::vector<N2> range(N start, N stop, N2 step)
std::vector<N2> range(N start, N stop, N2 step = N(1))
{
if (step == N2(0))
{
@ -119,21 +126,22 @@ namespace sfw
return result;
}
template <typename N>
std::vector<N> range(N start, N stop)
{
return range(start, stop, N(1));
}
/* If only one argument is provided, treat it as the stop value, and use 0 for start and 1 for step */
template <typename N>
std::vector<N> range(N stop)
{
return range(N(0), stop, N(1));
}
/* Return a vector of exactly count values from start to end, inclusive, with an even amount between each value */
template <typename N>
std::vector<float> range_count(N start, N end, int count)
{
/* negative or zero count is invalid */
if (count < 1)
{
throw std::invalid_argument("count argument must be greater than zero");
}
float step = (end - start) / (count - 1);
std::vector<float> all;
all.reserve(count);
@ -144,6 +152,8 @@ namespace sfw
return all;
}
/* Return a map where the keys are the percent way through the range from start to end each value is,
* with step between each value. End is not included in the range. */
template <typename N, typename N2 = N>
std::map<float, N2> range_percent(N start, N end, N2 step = N(1))
{
@ -157,9 +167,16 @@ namespace sfw
return range_percent_map;
}
/* Return a map where the keys are the percent way through the range from start to end (inclusive) each value is,
* with exactly count values in the range, spaced evenly. */
template <typename N>
std::map<float, float> range_percent_count(N start, N end, int count)
{
/* negative or zero count is invalid */
if (count < 1)
{
throw std::invalid_argument("count argument must be greater than zero");
}
std::map<float, float> range_percent_map;
std::vector<float> all = range_count(start, end, count);
int ii = 0;