Ensure all vector components are greater than some number - opengl

I have a vec2 containing x and y coordinates. I need to ensure that they are both greater than 16. My first attempt:
if (gl_FragCoord.xy > 16.0) {
// do something..
}
It fails to compile with a "no matching operand" error.
It works if I compare each dimension of the vector separately.
if ((gl_FragCoord.x > 16.0) && (gl_FragCoord.y > 16.0))
// do something..
}
Is there any better way to check all the elements of the vector at once?

There's a function for component-wise comparison that produces a boolean vector and then another one to check components of a boolean vector:
if (all(greaterThan(gl_FragColor.xy, vec2(16.0))) {
/* ... */
}

Related

How can write a mapping program in c++

I have a question about c++ and a problem which I have to solve. Actually, I don't have any idea about solving this problem. I'd be delighted if anyone could help me and give me any clues. Thanks
I want to print the output for every 2 natural numbers a, b which make a/b fraction.
for example for the number (2) it should print 1 1 in the output because we don't consider (0,0) and the second point which we reach in the coordinate on the spiral path is (1,1).
the input should be a natural number and the output should be vertical and horizontal coordinate.
for example, the input is 12 and its output is 2 2.
more information is here in these photos:
Nice question, not that easy to implement.
The approach is to first analyze the requirements, then do a design, refine the design until it is OK and finally, at the very end, write the code.
Let us look at the requirements
We have coordinate system, where we will move in
Movement will follow a spiral pattern
Already occupied coordinates in the coordinate system, cannot be reused
Fractions shall be generated, derived from the position in the coordinate system
Since a position with a column 0 would result in an illegal 0-denominator, the coordinate system will not have a column 0.
So, after moving to a new position, a reduced unique fraction shall be generated
A given number of moves shall be performed
According to the description, it would be sufficient to just show the last reduced fraction as a result. However, the whole sequence is of interest
Good. Now we have analyzed those requirements and know, what should be done.
Next step. We start to think on how the requirements shall be implemented.
Obviously, we need some implementation of a “fraction” class. The fraction class will only store reduced fractions. The sign will be normalized. Meaning, if there are signs, they are evaluated and if the resulting fraction is negative, the numerator will get the minus sign. All fractions having a 0 as numerator, will get a 1 as denominator. We use the one, because later, during output we will suppress the output of “1” denominator and show just the numerator.
All this we will do during creation of the fraction using the constructor. That is somehow simple.
The requirement of unique fractions, can be solved by storing them in an appropriate container. Because the order is not important (only the uniqueness), we can use a std::unordered_set. This has the additional advantage that we have fast access via hash algorithms. For that we need to add a hash function and an equal operator to our fraction class.
For reducing fractions, we will use the standard approach and divide numerator and denominator by the greatest common divisor (GCD). Luckily C++ has a ready to use function for this.
Last, but not least, we will overwrite the inserter operator <<, for generating some output easily.
Now, moving along a spiral pattern. A spiral pattern can be created by folling the following approach.
We have a start position and a start direction
Depending on the direction we will look for a potential next position and next direction. The idea to get a spiral is the following:
If current direction is right, then the preferred next direction is up
If current direction is up, then the preferred next direction is left
If current direction is left, then the preferred next direction is down
If current direction is down, then the preferred next direction is right
All the above of course only, if that new position is not occupied
To check, if a position is occupied, we will store all visited positions as unique value in a container.
We again need select the std::unordered_set
We need to add a hash functor for this
If the potential new position, calculated with the above logic, is free (not occupied / not in our std::unordered_set), then we will add the new position to it.
If the potential next position is already occupied, then we continue to move in the original direction
Moving along columns, we have to skip column 0. It is not existing.
After having the new position, we create a (reduced) fraction out of it. The row of the position will be the numerator, the column will be the denominator
Then, we check, if we have seen this fraction already, by trying to insert it into the above described std::unordered_set for the fractions (do not mix up with container for positions)
If it could be inserted, then it was not in before, so, it is no duplicate, and can be put into the result-vector
All the above (and a little bit more) can now be implemented into code.
This will lead to one of many potential solutions:
#include <iostream>
#include <numeric>
#include <vector>
#include <utility>
#include <unordered_set>
struct RFraction {
// We will store reduced fractions. And show numerator and denominator separately
int numerator{};
int denominator{};
// Contructor will take a fraction, a nominater and denominater, reduce the fraction and mormalize the sign
RFraction(const int n, const int d) : numerator(std::abs(n)), denominator(std::abs(d)) {
if (n == 0) denominator = 1; // All faction with a 0 numerator will get a 1 as denominator
reduce(); // Reduce fraction
if ((n < 0 and d >= 0) or (n >= 0 and d < 0)) numerator = -numerator; // Handle sign uniformly
}
// Simple reduce function using standardapproach with gcd
void reduce() { int gcd = std::gcd(numerator, denominator); numerator /= gcd; denominator /= gcd; }
// Hash Functor
struct Hash { size_t operator()(const RFraction& r) const { return std::hash<int>()(r.numerator) ^ std::hash<int>()(r.denominator); } };
// Equality, basedon fraction and not on a double
bool operator == (const RFraction& other) const { return numerator == other.numerator and denominator == other.denominator; }
// Simple output
friend std::ostream& operator << (std::ostream& os, const RFraction& f) {
if (f.denominator == 1) os << f.numerator;
else os << f.numerator << " / " << f.denominator;
return os;
}
};
using Position = std::pair<int, int>;
struct PairHash { std::size_t operator() (const Position& p) const { return std::hash<int>()(p.first) ^ std::hash<int>()(p.second); } };
using Matrix = std::unordered_set<Position, PairHash>;
using Sequence = std::vector<RFraction>;
using UniqueRFraction = std::unordered_set<RFraction, RFraction::Hash>;
enum class Direction { right, up, left, down };
Sequence getSequence(const size_t maxIndex) {
// Current position and direction
Position position{ 0,2 };
Direction direction{ Direction::right };
// Here we will store all occupied positions
Matrix matrix{ {0,1}, {0,2} };
// Thsi is a helper to store in the end only unique fractions
UniqueRFraction uniqueRFraction{ {0,1} };
// Result. All unique fractions along the path
Sequence result{ {0,1} };
// Find all elements of the sequence
for (size_t k{}; k < maxIndex; ) {
Position potentialNextPosition(position);
// Depending of the current direction, we want to get new position and new direction
switch (direction) {
case Direction::right:
// Check position above. Get position above current position
++potentialNextPosition.first;
// Check, if this is already occupied
if (matrix.count(potentialNextPosition) == 0) {
// If not occupied then use this new direction and the new position
direction = Direction::up;
position = potentialNextPosition;
}
// Keep on going right
else if(++position.second == 0) ++position.second;
break;
case Direction::up:
// Check position left. Get position left of current position
if(--potentialNextPosition.second == 0) --potentialNextPosition.second;
// Check, if this is already occupied
if (matrix.count(potentialNextPosition) == 0) {
// If not occupied then use this new direction and the new position
direction = Direction::left;
position = potentialNextPosition;
}
// Keep on going up
else ++position.first;
break;
case Direction::left:
// Check position below. Get position below current position
--potentialNextPosition.first;
// Check, if this is already occupied
if (matrix.count(potentialNextPosition) == 0) {
// If not occupied then use this new direction and the new position
direction = Direction::down;
position = potentialNextPosition;
}
// Keep on going left
else if (--position.second == 0) --position.second;
break;
case Direction::down:
// Check position right. Get position right of current position
if (++potentialNextPosition.second == 0) ++potentialNextPosition.second;
// Check, if this is already occupied
if (matrix.count(potentialNextPosition) == 0) {
// If not occupied then use this new direction and the new position
direction = Direction::right;
position = potentialNextPosition;
}
// Keep on going down
else --position.first;
break;
}
// Add new position to the matrix, to indicate that it is occuppied
matrix.insert(position);
// Check, if the fraction, created out of the position, is unique. If so, the add it to the result
if (const auto [iter, isOK] = uniqueRFraction.insert({ position.first, position.second }); isOK) {
result.push_back(*iter);
++k;
}
}
return result;
}
int main() {
// Calculate the sequence of fractions up to a given index (index starts with 0)
Sequence seq = getSequence(25);
// Shwo the result
std::cout << "\nResult: \t" << seq.back() << "\n\nSequence:\n\n";
// And for debug purposes, also the complete sequence.
for (size_t k{}; k < seq.size(); ++k)
std::cout << k << '\t' << seq[k] << '\n';
return 0;
}

Eigen error when initializing dynamic matrix

I am trying to populate an Eigen matrix (dyinamic rows, 2 columns, of doubles) from a vector containing some simple structure of cartesian points, however, I am getting an error when using operator <<.
Minimum failing example (using MSVC 2017):
#include <Eigen/Dense>
#include <vector>
struct point {
double x, y;
};
int main() {
std::vector<point> points = {
point{0.0, 0.0},
point{0.5, 0.0},
point{0.0, 1.0},
point{0.5, 1.0},
};
typedef Eigen::Matrix<double, Eigen::Dynamic, 2> CoordMatrix;
CoordMatrix X;
for (auto& p : points)
X << p.x, p.y;
return 0;
}
When running this, I get an error in the line X << point.x, point.y; saying: "No operator << matches these operands" (this also throws when trying to pass X << 0.0, 0.0; while in debug mode).
From what I understand, you are trying to initialize the X matrix with values in each row containing coordinates of one of the points from the earlier vector. You can't do it that way, see here:
Eigen offers a comma initializer syntax which allows the user to easily set all the coefficients of a matrix, vector or array. Simply list the coefficients, starting at the top-left corner and moving from left to right and from the top to the bottom. The size of the object needs to be specified beforehand. If you list too few or too many coefficients, Eigen will complain.
The above clearly states that you the right hand side needs to match dimensions to the left hand side. In your case you would probably need to copy the vector element by element. Something like:
CoordMatrix X(points.size(), 2); // reserving rigth storage for the matrix
for (auto i = 0u; i < points.size(); ++i) {
X(i, 0) = points[i].x;
X(i, 1) = points[i].y;
}
If you like to use the << initialization, you can do that one row at a time (and as #paler123 already said, you need to allocate X before storing values into it):
typedef Eigen::Matrix<double, Eigen::Dynamic, 2> CoordMatrix;
CoordMatrix X(points.size(), 2); // allocate space for matrix
Eigen::Index r=0; // or use `r` as counter in the loop
for (auto& p : points)
X.row(r++) << p.x, p.y; // fill matrix one row per iteration
You can also map the memory of points to an Eigen::Map directly -- in that case you must make sure that the storage order agrees and that points does not get modified if you still use X, but X will require no extra memory (except for a pointer and an Index).
typedef Eigen::Matrix<double, Eigen::Dynamic, 2, Eigen::RowMajor> CoordMatrix;
auto X = CoordMatrix::Map(&points[0].x, points.size(), 2); // no copy happens
// X gets invalid if `points` are destructed or re-allocated.

Sorting an array of structs in C++

I'm using a particle physics library written in c++ for a game.
In order to draw the particles I must get an array of all their positions like so..
b2Vec2* particlePositionBuffer = world->GetParticlePositionBuffer();
This returns an array of b2Vec2 objects (which represent 2 dimensional vectors in the physics engine).
Also I can get and set their colour using
b2ParticleColor* particleColourBuffer = world->GetParticleColorBuffer();
I would like to get the 10% of the particles with the highest Y values (and then change their colour)
My idea is..
1. Make an array of structs the same size as the particlePositionBuffer array, the struct just contains an int (the particles index in the particlePositionBuffer array) and a float (the particles y position)
2.Then I sort the array by the y position.
3.Then I use the int in the struct from the top 10% of structs in my struct array to do stuff to their colour in the particleColourBuffer array.
Could someone show me how to sort and array of structs like that in c++ ?
Also do you think this is a decent way of going about this? I only need to do it once (not every frame)
Following may help:
// Functor to compare indices according to Y value.
struct comp
{
explicit comp(b2Vec2* particlePositionBuffer) :
particlePositionBuffer(particlePositionBuffer)
{}
operator (int lhs, int rhs) const
{
// How do you get Y coord ?
// note that I do rhs < lhs to have higher value first.
return particlePositionBuffer[rhs].getY() < particlePositionBuffer[lhs].getY();
}
b2Vec2* particlePositionBuffer;
};
void foo()
{
const std::size_t size = world->GetParticleCount(); // How do you get Count ?
const std::size_t subsize = size / 10; // check for not zero ?
std::vector<std::size_t> indices(size);
for (std::size_t i = 0; i != size; ++i) {
indices[i] = i;
}
std::nth_element(indices.begin(), indices.begin() + subsize, indices.end(),
comp(world->GetParticlePositionBuffer()));
b2ParticleColor* particleColourBuffer = world->GetParticleColorBuffer();
for (std::size_t i = 0; i != subsize; ++i) {
changeColor(particleColourBuffer[i])
}
}
If your particle count is low, it won't matter much either way, and sorting them all first with a simple stl sort routine would be fine.
If the number were large though, I'd create a binary search tree whose maximum size was 10% of the number of your particles. Then I'd maintain the minY actually stored in the tree for quick rejection purposes. Then this algorithm should do it:
Walk through your original array and add items to the tree until it is full (10%)
Update your minY
For remaining items in original array
If item.y is less than minY, go to next item (quick rejection)
Otherwise
Remove the currently smallest Y value from the tree
Add the larger Y item to the tree
Update MinY
A binary search tree has a nice advantage of quick insert, quick search, and maintained ordering. If you want to be FAST, this is better than a complete sort on the entire array.

Cannot find the proper base case for a recursive function to 'generate' matrices?

I have a recursive function to generate matrices, called lights.
This function is called in light_and_color.
light_col_permutation, called in lights, gives a vector of vector of vector of int.
So, in the loop for(vector<vector<int> > aa:light_col_permutations(rowSums, colSums, colIndex)) in the code, aa gives a pair of vector.
aa[0] is the possible values that could go into the row of the matrix at index colIndex.
aa[1] is the updated (remaining) rowSums that could be filled in, for unfilled rows after colIndex. This is passed into lights recursively, to fill in the next column.
What this function is supposed to do is to find all matrices for each of aa in light_col_permutations.
With the base case in the code, it only finds one such matrix and quits(returns).
How can I generate all of them?
The following code is a simplified version, so that you can see the structure of the recursion. Please let me know if there is anything unclear. (the whole program is about 800 lines long, but I will post it if requested)
void lights(vector<int>& rowSums, vector<int>& colSums, int colIndex, matrix_c mc) {
if(colIndex == mc.r) {
mc.print_matrix();
}
for(vector<vector<int> > aa:light_col_permutations(rowSums, colSums, colIndex)) {
mc.row_assign(colIndex, aa[0]);
mc.newRowSum = aa[1];
lights(mc.newRowSum, colSums, colIndex+1, mc);
}
}
void light_and_color(int r, int n, int color, string filename) {
matrix_c mc(r, n); //zero matrix of size (r) X (r)
//here I get rowSums and colSums, but I omitted them
lights(rowSums, colSums, 0, mc);
}

OpenCV get condition base maximum element location from matrix

I have checked minMaxLoc but it just gives the maximum and minimum locations of the matrix. What i need to find is maximum or equal to some other digit . e.g. (abc >=7) then give all the locations from the matrix where this condition applies.
Matlab example :
[a,b] = find( heMap >= (max(max(heMap)) ) );
so how can i fulfill the condition in opencv for getting the particular maximum or minimum values.? kindly help
regards
Currently i am using this way
double getMaxValue(Mat hemap)
{
MatConstIterator_<double> it = hemap.begin<double>(), it_end = hemap.end<double>();
double maxdata=0;
for(; it != it_end; ++it)
{
if(*it>maxdata)
{
maxdata = *it;
}
}
return maxdata;
}
I don't know any built in function, that does exactly this. You can compare your matrix with an element which gives you a boolean matrix. But I don't know about any function that gives you the position of every non-zero element, like find.
But it is very simple to just loop over the array and do the comparison yourself:
int thresh = 50;
for(int y=0;y<matrix.rows; y++)
for(int x=0;x<matrix.cols; x++)
if( matrix.at<uchar>(y,x) >= thresh)
printf(" (%d,%d) = %d\n",x,y, matrix.at<uchar>(y,x));
How about cv::compare function, it compares each pixel with given number and sets the output array by 255 if the condition is satisfied else 0.
I give you a 2+1-step solution:
get maximum with minMaxLoc() -> max_val.
use inRange(input, max_val, max_val, output_mask) to get all the max elements white.
Decide what to do with these locations.
Say, you can easily detect hot spots, big blobs of max-es or
connected components of max-es. (with dilate and erode and then
using floodFill on the spot centres, one-by-one.)