Get a full double value - c++

I add one double value from a file to a variable and push it into a vector, with format "338620.3478" , then after that I get the value from the vector, it just gets "338620", as it could not get all the double value.
So how can I get a full double value like the original format?
The Code:
struct Point {
double x, y;
bool operator <(const Point &p) const {
return x < p.x || (x == p.x && y < p.y);
}
};
ifstream iFile("griddata.dat"); //read a file (grid)
string line;
Point Grid; /
while(getline(iFile,line))
{
unsigned pos = line.find(",");//the symbol is used to separate X and Y
std::string strs = line.substr(0,pos); // get X
std::string strs2 = line.substr(pos+1); // get Y
Grid.x = atof(strs.c_str()); // get the first cooordinate X
Grid.y = atof(strs2.c_str()); // get the second cooordinate Y
// A list of coordinates of grid is stored into the vector gridPoints
gridPoints.push_back(Grid); // adding the points of grid to vector
}
int j;
for(j=0;j<gridPoints.size();j++)
{
//here i cannot get the full double value for gridPoints[j].x;
//....it just gets "338620"
}
The format of file (griddata.dat):
338620.3478,6196150.566
Thank you!

Assuming that your Point class is in the windows framework, I'm pretty sure it's members are int types.
Either way, your values are being cast to a type that isn't floating point and is being truncated.

I think your problem is retrieving the values (maybe with cout?? -->then you can use: cout.precision(15))
see: How do I print a double value with full precision using cout?

Related

3D Vector - "No instance of overload function?"

Still relatively new to vectors in C++, the aim of this function is to take 4 arguments, 3 of which define the (x , y , z) position of the data being written, and the 4th being the value that is to be written.
as Requested, a picture of the errors is listed:
Picture of code listed above
The issue is under the "push_back" code. the "." after yy.push and xx.push is giving the error "no instance of overloaded function".
If somebody could explain what this means and how to fix it I would greatly appreciate it! :)
double datawrite(vector<unsigned int> xx, vector<unsigned int> yy,
vector<unsigned int> zz, double val) {
//Writes data to the 3d Vector
//finds coordinates for data
vector< vector< vector<unsigned int > > > xx;
vector< vector<unsigned int> > yy;
vector<unsigned int> zz;
//Writes value at proper position
zz.push_back(val);
yy.push_back(zz);
xx.push_back(yy);
//outputs value from vector
return val;
}
So you want a 3d matrix of doubles? First you need to create it:
#include <vector>
std::vector<vector<vector<double>>> matrix;
This creates a 3d matrix, but with 0 size. Next, when you add data to the matrix, you need to make sure the matrix is big enough:
// Co-ords are integers
double datawrite(int x, int y, int z, double val)
{
// Make sure vectors are large enough
if (matrix.size() < x+1) matrix.resize(x+1);
if (matrix[x].size() < y+1) matrix[x].resize(y+1);
if (matrix[x][y].size() < z+1) matrix[x][y].resize(z+1);
// Store the value
matrix[x][y][z] = val;
return val;
}
However, this is a bit messy and leaves the matrix in an incomplete state. For example, if you call datawrite(2, 3, 4, 9.9); this may appear that all indexes < 2,3,4 would be valid, but they are not. For example trying to read matrix[0][0][0] will give you an error.
You could work around this with a dataread function that checks the sizes of the vectors before trying to read from them.
If you know ahead of time how large the matrix is, you can create the entire matrix at once like this:
vector<vector<vector<double>>> matrix(10, vector<vector<double>>(10, vector<double>(10)));
This creates a complete 10x10x10 matrix. This ensures all indexes < 10 will be valid. I prefer this method. Then your function becomes:
double datawrite(int x, int y, int z, double val)
{
// Make sure indexes are valid
if (x >= matrix.size() || y >= matrix[x].size() || z >= matrix[x][y].size()) {
// Up to you what to do here.
// Throw an error or resize the matrix to fit the new data
}
// Store the value
matrix[x][y][z] = val;
return val;
}

Initializing a box with N particles arranged in a specific pattern

I'm new to C++, and as an exercise I'm trying to reproduce what was done by Metropolis et al. (Metropolis Monte Carlo).
What I have done thus far - Made 2 classes: Vector and Atom
class Vector {
public:
double x;
double y;
Vector() {
}
Vector (double x_, double y_) {
x = x_;
y = y_;
}
double len() {
return sqrt(x*x + y*y);
}
double lenSqr() {
return x*x + y*y;
}
};
class Atom {
public:
Vector pos;
Vector vel;
Vector force;
Atom (double x_, double y_) {
pos = Vector(x_, y_);
vel = Vector(0, 0);
force = Vector(0, 0);
}
double KE() {
return .5 * vel.lenSqr();
}
};
I am not certain that the way I have defined the class Atom is... the best way to go about things since I will not be using a random number generator to place the atoms in the box.
My problem:
I need to initialize a box of length L (in my case L=1) and load it with 224 atoms/particles in an offset lattice (I have included a picture). I have done some reading and I was wondering if maybe an array would be appropriate here.
One thing that I am confused about is how I could normalize the array to get the appropriate distance between the particles and what would happen to the array once the particles begin to move. I am also not sure how an array could give me the x and y position of each and every atom in the box.
Metropolis offset (hexagonal) lattice
Well, It seems, that generally you don't need to use array to represent the lattice. In practice most often it may sense to represent lattice as array only if your atoms can naturally move only on the cells (for example as figures in chess). But seems that your atoms can move in any direction (already not practicle to use such rigid structure as array, because it has naturally 4 or 8 directions for move in 2D) by any step (it is bad for arrays too, because in this case you need almost countless cells in array to represent minimal distance step).
So basically what do you need is just use array as storage for your 224 atoms and set particular position in lattice via pos parameter.
std::vector<Atom> atoms;
// initialize atoms to be in trigonal lattice
const double x_shift = 1. / 14;
const double y_shift = 1. / 16;
double x_offset = 0;
for (double y = 0; y < 1; y += y_shift){
for (double x = x_offset; x < 1; x += x_shift){
// create atom in position (x, y)
// and store it in array of atoms
atoms.push_back(Atom(x, y));
}
// every new row flip offset 0 -> 1/28 -> 0 -> 1/28...
if (x_offset == 0){
x_offset = x_shift / 2;
}
else{
x_offset = 0;
}
}
Afterwards you just need to process this array of atoms and change their positions, velocities and what you need else according to algorithm.

C++ Vector - Emplace/Erase not working?(Polymorphism)

I'm having some problems with polymorphism I have a superclass of CEntity, and a subclass of unit type, I am dynamic casting and removing and emplacing a new entity of the dynamic casts type at its place, I have the opposite problem of my previous question.
Problem is the values being set are not changing, it remains with default values, it appeared to work before but now it has stopped working, I'm not sure what has caused the issue.
specifically buildsetup, sets the x-y-z values of the unit subclass's x,y,z, but when I look inside the vector the values remain unchanged, this is strange because it does actually manage to change the values for whether the unit is alive or not.
void builder(int no, string in , int top, int bot, CTeam &team, string owner, string original)
{
for (int i = top; i <= bot; i++)
{
EntityUnit* a;
a = dynamic_cast<EntityUnit*>(AWorld.EntitiesVector[i]);
a->unit_alive;
if (a->unit_alive == false)
{
float x = Player.returncity_add().cit_ret_X();
float y = Player.returncity_add().cit_ret_Y();
float z = Player.returncity_add().cit_ret_Z();
cout << "X:" << x;
cout << "Y:" << y;
cout << "Z:" << z;
float cost = MainAB.UnitTemplates[no]->UDRetCost();
float health = MainAB.UnitTemplates[no]->UDRetMaxHealth();
float damage = MainAB.UnitTemplates[no]->UDRetStrength();
float speed = MainAB.UnitTemplates[no]->UDRetSpeed();
float buildtime = MainAB.UnitTemplates[no]->UDRetBuildTime();
int popcost = MainAB.UnitTemplates[no]->UDRetPop();
a->set_owner(owner);
setmodel(i, x, y, z); // takes an xyz by ref and sets the model
to them then changes the model's localz by -10
Units[i]->SetSkin(setskin(owner, original));
a->BuildSetup(x, y, z, health, damage, speed, buildtime, cost, popcost);
team.inc_popcount(a->UDRetPop());
a->set_unit_alive(true);
sBuildUnit.play();
AWorld.EntitiesVector.erase(AWorld.EntitiesVector.begin() + i);
AWorld.EntitiesVector.emplace(AWorld.EntitiesVector.begin() + i, new EntityUnit(a));
AWorld.EntitiesVector[i]->set_x(x);
AWorld.EntitiesVector[i]->set_y(y);
AWorld.EntitiesVector[i]->set_z(z);
break;
}
}
Entity build setup
void EntityUnit::BuildSetup(float x, float y, float z,float _health, float _damage, float _speed, float _buildtime, float _cost, int _popcost)
{
unit_x = x;
unit_y = y;
unit_z = z;
unit_health[0] = _health;
unit_health[1] = _health;
unit_damage = _damage;
speed = _speed;
buildtime = _buildtime;
cost = _cost;
CUnitType = NA;
pop_req = _popcost;
}
After static debugging it, it most definately emplaces a new unit with the updated -is_alive, and while a's values change at the point of unitbuild, when its emplaced all x,y,z's return to 9999, which was what it was when they were pushed on the vector.
When you call
AWorld.EntitiesVector.erase(AWorld.EntitiesVector.begin() + i);
you destroy the object pointed to by a. The subsequent reference to it on the next line is Undefined Behavior, and anything is possible.
I'm not sure why you erase the entity, then try to put a new one in the same place. If you structure your code right you should be able to just reuse the existing entity (pointed to by a) without the erase and emplace calls.
Ok, Apparently the problem was it was totally unnecessary to erase/emplace, as I get what you mean now returning a pointer, it edited the value... odd it didn't work last time.

Pushing NULL object into std::vector

I have a class called Pixel where I only store the values (x,y). Then I created a std::vector to store the pixels in a patch and compute some disparity.
Surprisingly, after some Pixels are push_back() into the vector I get a NULL reference but I don't see why. Here's my code
std::vector<Pixel*> disparityPatches;
std::vector<Pixel*> patchPos;
//COMPUTE THE DISPARITY FOR EACH OF THE PIXEL COORDINATES IN THE PATCH
for (uint iPatchPos = 0; iPatchPos < patchPos.size(); iPatchPos++)
{
disparityPatches.push_back(new Pixel(patchPos[iPatchPos]->getX()+dispNodeX, patchPos[iPatchPos]->getY()+dispNodeY));
if( (disparityPatches[disparityPatches.size()-1]) == NULL)
{
std::cout << "WHAT!?" << std::endl;
}
}
Can you see why is this hapenning? I've checked that patchPoshas the correct data and dispNodeX and dispNodeY have the correct info too.
It's weird because the first three iterations (iPatchPos = [0,1,2,3]) work fine then i get the NULL reference.
EDIT
class Pixel
{
float _x;
float _y;
public:
Pixel();
Pixel::Pixel(float x, float y)
{
_x = x;
_y = y;
}
const float Pixel::getX()
{
return _x;
}
const float Pixel::getY()
{
return _y;
}
};
You used below code to add a pix into the vector:
disparityPatches.push_back(new Pixel(patchPos[iPatchPos]->getX()+dispNodeX, patchPos[iPatchPos]->getY()+dispNodeY));
maybe new Pixel(patchPos[iPatchPos]->getX()+dispNodeX, patchPos[iPatchPos]->getY()+dispNodeY) may return null when the constructor failed in someway, so NULL will be added, then you got your error.

C++ Data Structure for storing 3 dimensions of floats

I've implemented a 3D strange attractor explorer which gives float XYZ outputs in the range 0-100, I now want to implement a colouring function for it based upon the displacement between two successive outputs.
I'm not sure of the data structure to use to store the colour values for each point, using a 3D array I'm limited to rounding to the nearest int which gives a very coarse colour scheme.
I'm vaguely aware of octtrees, are they suitable in this siutation?
EDIT: A little more explanation:
to generate the points i'm repeatedly running this:
(a,b,c,d are random floats in the range -3 to 3)
x = x2;
y = y2;
z = z2;
x2 = sin(a * y) - z * cos(b * x);
y2 = z2 * sin(c * x) - cos(d * y);
z2 = sin(x);
parr[i][0]=x;
parr[i][1]=y;
parr[i][2]=z;
which generates new positions for each axis each run, to colour the render I need to take the distance between two successive results, if I just do this with a distance calculation between each run then the colours fade back and forth in equilibrium so I need to take running average for each point and store it, using a 3dimenrsionl array is too coarse a colouring and I'm looking for advice on how to store the values at much smaller increments.
Maybe you could drop the 2-dim array off and use an 1-dim array of
struct ColoredPoint {
int x;
int y;
int z;
float color;
};
so that the code would look like
...
parr[i].x = x;
parr[i].y = y;
parr[i].z = z;
parr[i].color = some_computed_color;
(you may also wish to encapsulate the fields and use class ColoredPoint with access methods)
I'd probably think bout some kind of 3-d binary search tree.
template <class KEY, class VALUE>
class BinaryTree
{
// some implementation, probably available in libraries
public:
VALUE* Find(const KEY& key) const
{
// real implementation is needed here
return NULL;
}
};
// this tree nodes wil actually hold color
class BinaryTree1 : public BinaryTree<double, int>
{
};
class BinaryTree2 : public BinaryTree<double, BinaryTree1>
{
};
class BinaryTree3 : public BinaryTree<double, BinaryTree2>
{
};
And you function to retreive the color from this tree would look like that
bool GetColor(const BinaryTree3& tree, double dX, double dY, double& dZ, int& color)
{
BinaryTree2* pYTree = tree.Find(dX);
if( NULL == pYTree )
return false;
BinaryTree1* pZTree = pYTree->Find(dY);
if( NULL == pZTree )
return false;
int* pCol = pZTree->Find(dZ);
if( NULL == pCol )
return false;
color = *pCol;
return true;
}
Af course you will need to write the function that would add color to this tree, provided 3 coordinates X, Y and Z.
std::map appears to be a good candidate for base class.