SFML 2.4.2 getting localBounds before drawing sf::Text object - c++

I'm working on a project that needs some buttons done with SFML. We're using version 2.4.2. I've managed to accomplish everything but the text alignment, and I'm very confused as to what the problem is.
In order to set the text's alignment, I know that I must set its origin and position properly. Since people may change a button's text, I decided to put the alignment feature into the setString function.
For debugging purposes, I've added a couple of console outputs to show me some of my data. Here's what the function looks like:
void rgf::Button::setString(const sf::String & str)
{
text.setString(str);
std::cout << "Original Origin: " << text.getOrigin().x << ", " << text.getOrigin().y << std::endl;
std::cout << "Original Position: " << text.getPosition().x << ", " << text.getPosition().y << std::endl;
std::cout << "Original LocalBounds: " << text.getLocalBounds().width << ", " << text.getLocalBounds().height << std::endl;
auto textRect = text.getLocalBounds();
auto btnRect = body.getLocalBounds();
text.setOrigin(textRect.left + textRect.width / 2, textRect.height + textRect.height / 2);
text.setPosition(btnRect.left + btnRect.width / 2, btnRect.top + btnRect.height / 2);
std::cout << "New Origin: " << text.getOrigin().x << ", " << text.getOrigin().y << std::endl;
std::cout << "New Position: " << text.getPosition().x << ", " << text.getPosition().y << std::endl;
std::cout << "New LocalBounds: " << text.getLocalBounds().width << ", " << text.getLocalBounds().height << std::endl;
}
The console outputs all positons, new and old, as 0 (except new position which returns the expected coords of 50 and 25).
According to what I've found online, as soon as I set the text's string, my text object's localBounds should change. This doesn't happen unless the text has been drawn once already in an sf::RenderWindow.
I made it so that the button's function would set the string to another value, this had the effect of setting the origin and position properly. Setting the string's value in a container's constructor (before it is drawn) doesn't set the origin properly.
I've spent a day on this and I don't understand what I'm missing. Any help would be greatly appreciated.

The setFont() function was called after the setString() function, which meant that the localBounds were still 0, since there was no font to indicate a width or a height.

Related

Value passed to function doubling inside call

I'm currently having an issue with a function call of get_set() for a doubly-linked list class I am making. The function returns a vector of all the elements within the list from position_from to position_to. For the tests I am sending
dll_UT->get_set( dll_UT->size()/2+1 , dll_UT->size()-1)
however, the value of dll_UT->size() somehow doubles within the call. When called directly before in my COUT statement, it shows the correct value of 100, but when inside the function this turns to 200. I've left console logs below as well as screenshots of the test.cpp and doubly_linked_list.cpp.
Any help on this is greatly appreciated as I've never seen this type of behavior before and would like to understand why such a thing is occuring.
Doubly_linked_list get_set(unsigned position_from, unsigned_position to){
std::cout << "\n\t__NEW TEST__\nSize of size/2+1 = " << this->size()/2+1 << "\nSize of size()-1 = " << this->size()-1 << std::endl;
std::cout << "position_from = " << position_from << "\nposition_to = " << position_to << std::endl;
//value of position_from == 200, should be == this->size()/2+1 which = 100
std::vector<int> temp;
temp.reserve(position_to - position_from);
while(position_from < position_to){
temp.push_back( this->get_data(position_from) );
position_from++;
}
temp.push_back(this->get_data(position_to));
std::cout << "Size of position_from = " << position_from << "\nSize of position_to = " << position_to << "\n\t__END TEST__" << std::endl;
return temp;```
}
Test.cpp {
```std::cout << "\nTEST.cpp::: dll_UT-size() = " << dll_UT->size() <<
"\nTEST.cpp::: dll_UT-size()/2+1 = " << dll_UT->size()/2+1 << std::endl;
//assuring dll_UT->size()/2+1 = 100
std::cout << "\nTEST.cpp::: expected_set.size() = " << expected_set.size() <<
"\nTEST.cpp::: expected_set.begin()+expected_set.size()/2+1 = " << expected_set.size()/2+1 << std::endl;
ASSERT_EQ(std::vector<int> (expected_set.begin()+expected_set.size()/2+1,expected_set.end()),
dll_UT->get_set( dll_UT->size()/2+1 , dll_UT->size()-1));//second half of data
// ^first operand doubled, ^second operand fine
//actually value sent is 200. dll_UT->size() is somehow doubling and equaling 400 but only for first operand of get_set(unsigned, unsigned)
Updated Caputre

Display Values inside Vector<RECT> array

I am using a code that stores points into a Vector data type as follows:
RECT head;
head.left = pt1.x;
head.right = pt2.x;
head.top = pt1.y;
head.bottom = pt2.y;
detectBox->push_back(head);
This falls inside a function that has a for loop that stores multple instances of "head" into the detectBox. This function is delared like this:
void GetHeads(cv::Mat Img, vector<RECT>* detectBox)
Where Img is just a normal black and white image being fed in with the heads that have been extracted through other processes. My question now is how to I see the points that have been stored inside of detectBox? I would like to access them outside of the for loop to use for other things. When i try and print out the variables Ive only been able to have the addresses returned (0000004FA8F6F31821, etc)
Also, detectBox is a shade of grey in the code(not sure what that means).
Full code can be found in my other question related to the same function, here:
C++ CvSeq Accessing arrays that are stored
-----EDIT-----
Methods tried and associated errors/Outputs:
First:
std::cout << "Back : " << &detectBox->back << std::endl;
'&': illegal operation on bound member function expression
Second:
std::cout << "Back : " << detectBox->back << std::endl;
'std::vector>::back': non-standard syntax; use '&' to create a pointer to member
Third:(Note, No Error, but no useful information output)
std::cout << "Detect Box : " << detectBox << std::endl;
Detect Box : 00000062BF0FF488
Fourth:
std::cout << "Detect Box : " << &detectBox[1] << std::endl;
Detect Box : 000000CB75CFF108
First, detectBox is a pointer to the array so it needs to be dereferenced before trying to index into it.
std::cout << (*detectBox)[1]; // Outputs the 2nd RECT in the vector
// assuming an operator<< is implemented
// for RECT.
Including the address of '&' operator before it will print out the address of the 2nd RECT instance at index 1 which you do not need to do because the index operator gives you the reference.
std::cout << &(*detectBox)[1];
Without an operator<< for the RECT instance to output it to the stream you will need to access the members directly. The following should work:
std::cout << "Left: " << (*detectBox)[1].left;
std::cout << "Right: " << (*detectBox)[1].right;
std::cout << "Top: " << (*detectBox)[1].top;
std::cout << "Bottom: " << (*detectBox)[1].bottom;
This can be improved by saving off a reference to the RECT you are trying to get first and then using that:
RECT& secondRect = (*detectBox)[1];
std::cout << "Left: " << secondRect.left;
std::cout << "Right: " << secondRect.right;
std::cout << "Top: " << secondRect.top;
std::cout << "Bottom: " << secondRect.bottom;
Finally, I notice that you push the new RECT on the back of the Vector, but then you always output the 2nd RECT in the vector. Assuming you want to print the RECT you just added you could either output the head local variable or use the back() method on the vector as so:
RECT& lastRect = detectBox->back();
std::cout << "Left: " << lastRect.left;
std::cout << "Right: " << lastRect.right;
std::cout << "Top: " << lastRect.top;
std::cout << "Bottom: " << lastRect.bottom;
detectBox->push_back(head);
std::cout << &detectBox[1];
Unless you've got an overloaded operator "<<" for RECT (which you probably don't) it's going to try and match this to the best thing it can, which clearly isn't going to be what you want it to be.
Try something more like
std::cout << "L: " << &detectBox[1].left <<
"R: " << &detectBox[1].right << std::endl
I'd also be worried that you're using [1] when what you probably want is ->back()

Display All vectors inside of a RECT array C++

This is my third question on this topic, Instead of asking a new question in the comments I thought it would be better to start a new thread.
The full code can be found here:
C++ CvSeq Accessing arrays that are stored
And using the following code I can display the most recent vector that has been added to the RECT array(Note that this is placed inside of the for loop):
RECT& lastRect = detectBox->back();
std::cout << "Left: " << lastRect.left << std::endl;
std::cout << "Right: " << lastRect.right << std::endl;
std::cout << "Top: " << lastRect.top << std::endl;
std::cout << "Bottom: " << lastRect.bottom << std::endl;
What I am now trying to do is create a loop outside of this for loop that will display all of the vectors present in detectBox. I havent been able to determine how many vectors are actually present in the array, and therefore cannot loop through the vectors.
I tried using the following:
int i = 0;
while ((*detectBox)[i].left!=NULL)
{
std::cout << "Left: " << (*detectBox)[i].left << std::endl;
std::cout << "Right: " << (*detectBox)[i].right << std::endl;
std::cout << "Top: " << (*detectBox)[i].top << std::endl;
std::cout << "Bottom: " << (*detectBox)[i].bottom << std::endl;
i++;
}
And have also tried playing around with sizeof(*detectBox) , but only have an answer of 32 being returned...
Okay, you are using the wrong terms here. The variable detectBox is a vector (or rather a pointer to a vector it seems). There are three ways to iterate over it (I'll show them a little later). It is not an array, it is not an array of vectors. It is a pointer to a vector of RECT structures.
Now as for how to iterate over the vector. It is like you iterate over any vector.
The first way is to use the C way, by using indexes:
for (unsigned i = 0; i < detectBox->size(); ++i)
{
RECT rect = detectBox->at(i);
std::cout << "Left: " << rect.left << std::endl;
...
}
The second way is the traditional C++ way using iterators:
for (std::vector<RECT>::iterator i = detectBox->begin();
i != detectBox->end();
++i)
{
std::cout << "Left: " << i->left << std::endl;
...
}
The last way is to use range for loops introduced in the C++11 standard:
for (RECT const& rect : *detectBox)
{
std::cout << "Left: " << rect.left << std::endl;
...
}
The propblem with your attempt of the loop, with the condition (*detectBox)[i].left!=NULL is that the member variable left is not a pointer and that when you go out of bounds you are not guaranteed to have a "NULL" value (instead it will be indeterminate and will seem random).

C++ inheritance of private functions while using PCL

I've been trying to use the PCA module from PCL in C++, but it's been a pain. At one point I want to switch the current indices of points that need to be operated on using the setIndices() function, but to actually make the update there is a private inherited function that one HAS to use called initCompute() or else it doesn't change them (or at least that is how I understood it). Never the less, the code as is, doesn't update the indices for some reason. This is the documentation for the class and everything works, but I have no idea how to make a workaround for this function which they intended to be used for these purposes:
http://docs.pointclouds.org/trunk/classpcl_1_1_p_c_a.html
How to deal with this? This is the error while compiling.
In function ‘void clustering(pcl::PointCloud<pcl::PointXYZ>::ConstPtr, pcl::PointCloud<pcl::PointXYZL>::Ptr, pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZ>::Ptr, float)’:
/usr/include/pcl-1.7/pcl/common/impl/pca.hpp:64:1: error: ‘bool pcl::PCA<PointT>::initCompute() [with PointT = pcl::PointXYZ]’ is private
pcl::PCA<PointT>::initCompute ()
This is the code:
pcl::PCA<pcl::PointXYZ> cpca = new pcl::PCA<pcl::PointXYZ>;
cpca.setInputCloud(input);
std::cout << "We're now performing the cluster elimination!" << endl;
Eigen::Matrix3f pca_matrix; //serves to hold the eigenvectors, and never got updated...hence the couts for checking.
for (int i = 0; i < nclusters; ++i, n++)
{
// the next two lines had to be done so, I found that in a forum, the library just behaves a bit strange.
pcl::PointIndices::Ptr pi_ptr(new pcl::PointIndices);
pi_ptr->indices = cluster_indices[i].indices;
cout << "Current size is: " << pi_ptr->indices.size() << endl;//this shows different sizes on every turn
//now can use pi_ptr
cpca.setIndices(pi_ptr);
pca_matrix = cpca.getEigenVectors();
// but here I get the same vectors every time
std::cout << "vector " << n << " " << pca_matrix(0,0) << " " << pca_matrix(0,1) << " " << pca_matrix(0,2) << endl;
std::cout << "vector " << n << " " << pca_matrix(1,0) << " " << pca_matrix(1,1) << " " << pca_matrix(1,2) << endl;
std::cout << "vector " << n << " " << pca_matrix(2,0) << " " << pca_matrix(2,1) << " " << pca_matrix(2,2) << endl;
Anyway, I got annoyed after a while and did the following.
I created a pca object at the beginning of a for loop using a pointer, and then deleted it at the end of the loop with delete. It is some allocing and deallocing going on there which is most likely not optimal, but it did the trick. The PCA object itself was only 144 bytes large, cause it mostly uses pointers to address necessary elements.

Wrong inexact intersection between 3D triangles (CGAL)

I'm having a really weird bug when trying to intersect two triangles inside a 3D space while using the CGAL::Exact_predicates_inexact_constructions_kernel kernel. Essentially, I have two triangles that should not intersect. The function CGAL::do_intersect returns always false when testing them, but the function CGAL::intersection builds an intersection, depending on the order of the vertices of the triangles.
The bug disappears when I use the CGAL::Exact_predicates_exact_constructions_kernel kernel, but I can't afford to use it in the real case scenario.
Below is a minimal code with the bug. Triangles B and C are equal (up to a permutation of the vertices), and should return the same intersection with Triangle A.
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Intersections.h>
#include <iostream>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Triangle_3 Triangle_3;
int main(int argc, char *argv[])
{
std::vector<Point_3> APoints(3);
std::vector<Point_3> BPoints(3);
APoints[0] = Point_3(2, 2, 0.9423616295572568);
APoints[1] = Point_3(0.9685134704003172, 2, 0.9678422992674797);
APoints[2] = Point_3(2, 1.124710354419025, 1.068692504586136);
BPoints[0] = Point_3(2.5, 2.5, 1.442361629557257);
BPoints[1] = Point_3(1.588259113885977, 2.5, 0.5);
BPoints[2] = Point_3(2.5, 1.624710354419025, 1.568692504586136);
Triangle_3 TriangleA(APoints[0],APoints[1],APoints[2]);
Triangle_3 TriangleB(BPoints[0],BPoints[1],BPoints[2]);
Triangle_3 TriangleC(BPoints[2],BPoints[1],BPoints[0]);
std::cout.precision(16);
std::cout << " - Tried to intersect: " << std::endl;
std::cout << " - Triangle (A) " << " : "
<< "(" << TriangleA.vertex(0) << ") "
<< "(" << TriangleA.vertex(1) << ") "
<< "(" << TriangleA.vertex(2) << ") " << std::endl;
std::cout << " - Triangle (B) " << " : "
<< "(" << TriangleB.vertex(0) << ") "
<< "(" << TriangleB.vertex(1) << ") "
<< "(" << TriangleB.vertex(2) << ") " << std::endl;
std::cout << " - Triangle (C) " << " : "
<< "(" << TriangleC.vertex(0) << ") "
<< "(" << TriangleC.vertex(1) << ") "
<< "(" << TriangleC.vertex(2) << ") " << std::endl;
if( TriangleB.vertex(0)==TriangleC.vertex(2) &&
TriangleB.vertex(1)==TriangleC.vertex(1) &&
TriangleB.vertex(2)==TriangleC.vertex(0))
{
std::cout << " - Triangles (B) and (C) have the same vertices " << std::endl;
}
bool bIntersectAB = CGAL::do_intersect(TriangleA,TriangleB);
bool bIntersectAC = CGAL::do_intersect(TriangleA,TriangleC);
bool bIntersectInexactAB = CGAL::intersection(TriangleA,TriangleB);
bool bIntersectInexactAC = CGAL::intersection(TriangleA,TriangleC);
if(bIntersectAB)
{
std::cout << " --> A and B are intersecting (exact) ..." << std::endl;
}
if(bIntersectAC)
{
std::cout << " --> A and C are intersecting (exact) ..." << std::endl;
}
if(bIntersectInexactAB)
{
std::cout << " --> A and B are intersecting (inexact) ..." << std::endl;
}
if(bIntersectInexactAC)
{
std::cout << " --> A and C are intersecting (inexact) ..." << std::endl;
}
return 0;
}
Here's the output ...
- Tried to intersect:
- Triangle (A) : (2 2 0.9423616295572568) (0.9685134704003172 2 0.9678422992674797) (2 1.124710354419025 1.068692504586136)
- Triangle (B) : (2.5 2.5 1.442361629557257) (1.588259113885977 2.5 0.5) (2.5 1.624710354419025 1.568692504586136)
- Triangle (C) : (2.5 1.624710354419025 1.568692504586136) (1.588259113885977 2.5 0.5) (2.5 2.5 1.442361629557257)
- Triangles (B) and (C) have the same vertices
--> A and C are intersecting (inexact) ...
... and a figure with the two triangles (A: vertices 1, 2, 3 ; B: vertices 11,12,13) and the "intersection" (segment 21 - 22), found using a similar version of this program.
What could be wrong? I'm using CGAL 4.6.1 on OS X 10.10.5 (Yosemite). Thanks in advance!
I've also sent this question to CGAL's mailing list, and the developers answered that this behaviour is not a bug, although
it is unfortunate. intersection is a generic function, implemented the same way for all CGAL kernels, and it uses one step that is not always handled correctly by inexact kernels - hence the intersection error. According to this thread at CGAL's GitHub page,
In order to keep using a kernel with inexact constructions, I usually advice to first call the do_intersect predicate and then call the intersection function using EPECK on primitives converted on the fly using CGAL::Cartesian_converter. You'll have to convert the output using another CGAL::Cartesian_converter. The call to do_intersect is not mandatory, it usually depends on your setting.