I create a boost polygon with 5 vertices, but when I display the vertices or
#include <boost/polygon/polygon.hpp>
.
.
.
void displayPolygon(boost::polygon::polygon_90_data<int> const& polygon, std::string name)
{
std::cout << std::endl << "polygon " << name << std::endl;
for (boost::polygon::polygon_90_data<int>::iterator_type it = polygon.begin(); it != polygon.end(); it++)
{
std::cout << (*it).x() << "/" << (*it).y() << "->";
}
std::cout << std::endl;
}
.
.
.
void testPolygon2()
{
//typedef
typedef boost::polygon::polygon_90_data<int> Polygon90Type;
typedef std::vector<Polygon90Type> Polygon90Set;
typedef boost::polygon::polygon_data<int> PolygonType;
typedef std::vector<PolygonType> PolygonSet;
typedef boost::polygon::point_data<int> PointType;
typedef std::vector<PointType> PointSet;
typedef boost::polygon::polygon_traits<Polygon90Type>::point_type Point;
Polygon90Type polygon_1;
Point pts_1[6] = { Point(0,0), Point(0,10), Point(5,12), Point(10,10), Point(10,0), Point(0,0)};
polygon_1.set(pts_1, pts_1 + 6);
std::cout << "polygon_1 area is " << boost::polygon::area(polygon_1) << std::endl;
std::cout << std::endl << __LINE__ << " :
Polygon90Set polygonSet;
polygonSet.push_back(polygon_1);
//an attempt to see result of bloating with 0
boost::polygon::bloat(polygonSet, 0, 0, 0, 0);
std::cout << "nb polygon bloated " << polygonSet.size() << std::endl;
for (auto polygon : polygonSet)
{
std::cout << std::endl << __LINE__ << "####################################" << std::endl;
displayPolygon(polygon, "2 - after being bloated");
std::cout << "area is " << boost::polygon::area(polygon) << std::endl;
}
}
the area it does not correspond to the polygon created.
the area should be 110 but is displayed as 100?
the vertices should be (0,0), (0,10), (5,12), (10,10), (10,0) but are (0/10), (5/10) ,(5/10), (10/10), (10/0), (0/0). It looks like the point (/5/12) is dismissed and replaced with point (5/10).
What am I doing wrong?
thanks.
Related
I have a std::vector<std::string>>. Following is my full program:
#include <iostream>
#include <vector>
#include <string>
#include <map>
int main() {
std::cout << " -- Beginining of program -- " << std::endl;
std::map<std::string, std::vector<std::string>> my_map_2;
std::vector<std::string> s = {"a", "b", "c"};
my_map_2.insert(std::make_pair("key1", s));
std::vector<std::string> s2 = {"d", "e", "f"};
my_map_2.insert(std::make_pair("key1", s2));
for(auto const &map_item: my_map_2) {
std::cout << map_item.first << " " << map_item.second[0] << std::endl;
std::cout << map_item.first << " " << map_item.second[1] << std::endl;
std::cout << map_item.first << " " << map_item.second[2] << std::endl;
std::cout << map_item.first << " " << map_item.second[3] << std::endl;
std::cout << map_item.first << " " << map_item.second[4] << std::endl;
std::cout << map_item.first << " " << map_item.second[5] << std::endl;
}
std::cout << " -- End of program -- " << std::endl;
return 0;
}
Problem:
I don't see the items of s2 when I print values of my_map_2. I see them only if I add s2 with a new key! If I do my_map_2.insert(std::make_pair("key2", s2)) instead of my_map_2.insert(std::make_pair("key1", s2)), I do see the items.
Question:
So, my question is, how to I append more items to the vector pointed to by key1 of my_map_2?
The below fails because the key is already taken:
std::vector<std::string> s2 = {"d", "e", "f"};
my_map_2.insert(std::make_pair("key1", s2)); // fails
To append to the mapped vector, you could do like this:
auto& vec = my_map_2["key1"]; // get reference to the existing vector
vec.insert(vec.end(), s2.begin(), s2.end()); // append to it
To view the keys and all the values in the vector you could change your loop to this:
for(auto const&[key, value]: my_map_2) {
for(const std::string& str : value) {
std::cout << key << ' ' << str << '\n';
}
}
my_map_2["key1"] is always a valid vector. You can insert into it directly
#include <iostream>
#include <vector>
#include <string>
#include <map>
int main() {
std::cout << " -- Beginining of program -- " << std::endl;
std::map<std::string, std::vector<std::string>> my_map_2;
std::vector<std::string> s = {"a", "b", "c"};
my_map_2["key1"].insert(my_map_2["key1"].end(), s.begin(), s.end());
std::vector<std::string> s2 = {"d", "e", "f"};
my_map_2["key1"].insert(my_map_2["key1"].end(), s2.begin(), s2.end());
for(auto const &map_item: my_map_2) {
for(auto const &value: map_item.second) {
std::cout << map_item.first << " " << value << std::endl;
}
}
std::cout << " -- End of program -- " << std::endl;
return 0;
}
Get iterator to key1, and just pushs back new items to existing vector:
std::vector<std::string> s2 = {"d", "e", "f"};
auto it = my_map_2.find("key1");
if (it != my_map_2.end())
std::move(s2.begin(), s2.end(), std::back_inserter(it->second));
else
my_map_2.insert(std::make_pair("key1",std::move(s2)));
To see: d,e,f you have to access 3,4 and 5 indices of vector. (You want to append new items, or just override existed items for given key?)
I have this example which is a function that returns a std::pair which holds a string value and its size.
std::pair<std::string, int> getLastPair(const vector<string>& vec) {
return{ vec.back(), vec.back().size() };
}
int main(){
vector<string> names{ "An", "Apple", "A", "Day", "Keeps", "The",
"Doctor", "Away"};
auto p{getLastPair(names)}; // ok p is a pair<string, int>
std::cout << p.first << " " << p.second << std::endl;
std::cout << typeid(p).name() << std::endl;
auto p2 = { getLastPair(names) }; // why it is not a pair but an initializer list?
std::cout << typeid(p2).name() << std::endl; // initializer list
std::pair<std::string, int> p3 = { getLastPair(names) }; // ok a pair
std::cout << p3.first << " : " << p3.second << std::endl;
decltype (getLastPair(names)) p4 = { getLastPair(names) }; // ok
std::cout << p4.first << " : " << p4.second << std::endl; // ok
}
Why the first initialization returns a pair as expected but the second one p2 is not a pair but an initializer_list instead?
As you can see p3 works fine (returns a pair) aslong as I've provided the type explicitly!?
Is the problem in Type Specifier auto?
Also p4 works fine with decltype.
I have a struct that represents a 3D position. Sometimes it's convenient to access the individual components and sometimes it's convenient to access all components as a vector (physics vector not std::vector) for which I'm using the Eigen linear algebra library. Since there are only three elements (x, y, z) and will only ever be three elements, is there anything wrong with the struct having three double& that refer to the elements of the Eigen Matrix? i.e.:
using ColumnVector3 = Eigen::Matrix<double, 3, 1>;
struct EnuPosition
{
EnuPosition(): pos(ColumnVector3::Zero()), east(pos[0]), north(pos[1]), up(pos[2]) {}
EnuPosition(double east, double north, double up): pos((ColumnVector3() << east, north, up).finished()),
east(pos[0]), north(pos[1]), up(pos[2]) {}
EnuPosition(const ColumnVector3& position): pos(position), east(pos[0]), north(pos[1]), up(pos[2]) {}
EnuPosition(const EnuPosition& enu):pos(enu.pos), east(pos[0]), north(pos[1]), up(pos[2]) {}
EnuPosition& operator=(const EnuPosition& enu)
{
this->pos = enu.pos;
return *this;
}
ColumnVector3 pos;
double& east;
double& north;
double& up;
};
It compiles fine with no warnings on g++ 5.5 with -Wall -Wextra -pedantic in the use cases I can think of:
int main ()
{
EnuPosition enu{12.5, 34.2, 99.2};
std::cout << "east: " << enu.east
<< " north: " << enu.north
<< " up: " << enu.up
<< std::endl;
ColumnVector3 x;
x << 2.0,3.0,4.0;
enu.pos = x;
std::cout << "east: " << enu.east
<< " north: " << enu.north
<< " up: " << enu.up
<< std::endl;
Eigen::MatrixXd y;
y.resize(3,1);
y << 7.6,8.7,9.8;
enu.pos = y;
std::cout << "east: " << enu.east
<< " north: " << enu.north
<< " up: " << enu.up
<< std::endl;
Eigen::Matrix<double,3,3> R;
enu.east = 1;
enu.north = 1;
enu.up = 1;
R << 1,2,3,4,5,6,7,8,9;
enu.pos = (R * enu.pos).eval();
std::cout << "east: " << enu.east
<< " north: " << enu.north
<< " up: " << enu.up
<< std::endl;
EnuPosition enu2 = enu;
std::cout << "east: " << enu2.east
<< " north: " << enu2.north
<< " up: " << enu2.up
<< std::endl;
}
Like I said, it works, I'm just curious if it's legal and not relying on undefined behavior, etc. Or are there other issues to be cognizant of?
After you added the copy-assignment your code should be safe.
However, if you are ok with writing east() instead of east in your code, then a slightly more elegant solution might be this:
using ColumnVector3 = Eigen::Matrix<double, 3, 1>;
struct EnuPosition : public ColumnVector3
{
EnuPosition(): ColumnVector3(ColumnVector3::Zero()) {}
EnuPosition(double east, double north, double up): ColumnVector3(east, north, up) {}
template<class X>
EnuPosition(const X& other): ColumnVector3(other) {}
double& east() {return this->x();}
double const& east() const {return this->x();}
double& north() {return this->y();}
double const& north() const {return this->y();}
double& up() {return this->z();}
double const& up() const {return this->z();}
};
If you intentionally don't want to inherit, you can of course still store the ColumnVector3 as a member.
int main() {
int x = 3613;
std::cout << "x= " << x << std::endl;
std::string xBin = std::bitset<16>(x).to_string();
std::cout << xBin << std::endl;
unsigned long xDecimal = std::bitset<16>(xBin).to_ulong();
std::cout << xDecimal << std::endl;
std::cout << std::endl << std::endl;
int b01 = 0b11001;
std::cout << "b01= " << b01 << std::endl;
int b02 = 0b1010;
std::cout << "b02= " << b02 << std::endl;
int b03 = b01 + b02;
std::cout << "int b03 = b01 + b02 = " << b03 << std::endl;
return 0;
}
Output:
x= 3613
0000111000011101
3613
b01= 25
b02= 10
int b03 = b01 + b02 = 35
With binary literals we can do normal arithmetic operations, while with the strings obtained with std::bitset<> this is not possible.
So...the question is: how to "compose" the binary literals, for example through the conversion from decimal to binary as obtained using std::bitset<> ?
Looking forward to your kind help. Marco
You shouldn't operate on bitsets by converting them to string and back - that's missing the point of bitsets... Instead you operate on them by using binary operators: &, |, ^, ... (just like you would on usual integers).
std::cout << std::bitset<3>(4) << " or "
<< std::bitset<3>(2) << " = "
<< (std::bitset<3>(4) | std::bitset<3>(2)) << std::endl;
Prints: 100 or 010 = 110
You can find all operators on wiki: http://en.cppreference.com/w/cpp/utility/bitset
How can I reach global variables from inner scopes, given the following code sample, how can I reach the global string X from the main function and from the most inner scope as well, also is the most inner scope is accessible once we quit it to the main scope or other scope?
#include <iostream>
#include <string>
std::string x = "global";
int counter = 1;
int main()
{
std::cout <<counter ++ << " " << x << std::endl;
std::string x = "main scope";
std::cout <<counter ++ << " " << x << std::endl;
{
std::cout <<counter ++ << " " << x << std::endl;
std::string x = "inner scope";
std::cout <<counter ++ << " " << x << std::endl;
}
std::cout <<counter++ << " " << x << std::endl;
}
the cout currently is:
1 global
2 main scope
3 main scope
4 inner scope
5 main scope
Global scope can be reached by using ::x, as per:
#include <iostream>
#include <string>
std::string x = "global";
int counter = 1;
int main()
{
std::cout << counter++ << " " << x << std::endl;
std::string x = "main scope";
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
{
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
std::string x = "inner scope";
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
}
std::cout << " " << ::x << std::endl;
std::cout << counter++ << " " << x << std::endl;
}
which gives you:
1 global
global
2 main scope
global
3 main scope
global
4 inner scope
global
5 main scope
The hard bit is actually getting to the intermediate scopes, such as main scope when you're withing the inner scope.
One way to do that is with references:
#include <iostream>
#include <string>
std::string x = "outer";
int main()
{
std::cout << "1a " << x << "\n\n";
std::string x = "middle";
std::cout << "2a " << ::x << '\n';
std::cout << "2b " << x << "\n\n";
{
std::string &midx = x; // make ref to middle x.
std::string x = "inner"; // hides middle x.
std::cout << "3a " << ::x << '\n';
std::cout << "3b " << midx << '\n'; // get middle x via ref.
std::cout << "3c " << x << "\n\n";
}
}
which gives:
1a outer
2a outer
2b middle
3a outer
3b middle
3c inner
But, as good advice, you'll find you won't have anywhere near as many problems if you:
name your variables a little more intelligently so as to avoid clashes; and
avoid global variables like the plague :-)
And, as for the variables in inner scopes, they cease to be available once you leave that scope, even with a reference (you can copy them to a variable with an larger scope but that's not the same as accessing the inner-scoped variable).