Matlab class multiple accessors for same data - c++

I'm trying to translate a class from C++ to Matlab. In C++, the same data can be accessed in multiple ways because the values are declared as a union.
However, it seems like the only way to do this in Matlab is to override subsref and subsasgn, which opens up a can of worms of having to parse methods.
Is there a different way to handle this? I saw some comments from 2014 indicating there wasn't
This is the C++ enum in question:
template <class T>
class Euler
{
public:
union
{
T m[3];
struct
{
union { T x; T yaw; T psi; }; // m[0]
union { T y; T pitch; T theta; }; // m[1]
union { T z; T roll; T phi; }; // m[2]
};
};
};

The simple solution: forget about these names, and translate this class as a simple array, indexing m.x as m[1], m.roll as m[2], etc. This might not be great for some use cases, but certainly is the most efficient solution.
The alternative solution requires creating a custom class. subsref and subsasgn are not necessary, it is possible to declare dependent properties and define getters and setters (though it's not pretty!):
classdef Euler
properties
x = 0;
y = 0;
z = 0;
end
properties (Dependent)
yaw, pitch, roll;
psi, theta, phi;
end
methods
function value = get.yaw(obj)
value = obj.x;
end
function value = get.pitch(obj)
value = obj.y;
end
function value = get.roll(obj)
value = obj.z;
end
function obj = set.yaw(obj,value)
obj.x = value;
end
function obj = set.pitch(obj,value)
obj.y = value;
end
function obj = set.roll(obj,value)
obj.z = value;
end
% Add same methods for psi, theta, phi.
end
end
You can now do:
e = Euler;
e.x = 1;
e.yaw % returns 1
e.roll = 5;
e.z % returns 5
That is, the object has properties x, y, z, yaw, pitch and roll (and after adding appropriate setters and getters also psi, theta and phi), but only stores three values. The values of e.g. yaw and x are linked, and always identical.

Related

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.

Adding a list of forces to a particle in c++

I'm kinda new to c++, so sorry if it's a dumb question.
I have a struct that represents a particle in a particle system. Along with the standard stuff like position, velocity, and mass, I want to give it a list of forces, such that each force is a function, where I pass it the particle, and based on the current state of the particle (or not), this function returns a force vector. Ideally I would sum up the results of every such force vector to get a net force, which I could then use to calculate the velocity of the particle for the next tick.
This is what I want my particle to look like
struct particle {
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
std::list<function> forces;
};
Now my question is: Can I do this without implementing a generic force base class that implements a function to calculate a force? Is there a way I can just specify a list of functions with the same call signature?
If you can guarantee that all functions will have the same method signature, then you can use the templated function[cppreference.com] class. I've modified your sample to illustrate how to use it.
#include <functional>
#include <list>
#include <cmath>
using namespace std;
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
// A list of forces that take a particle and return a double
// The space between the two > symbols is needed in pre-c++11 compilers.
list<function<double(const particle&)> > forces;
};
// An example function to calculate the force due to gravity.
double gravity(const particle& p)
{
return p.mass * -9.8;
}
// Making something up for air resistance
double resistance(const particle& p)
{
return 0.1 * sqrt(p.dx * p.dx + p.dy * p.dy + p.dz * p.dz);
}
int main()
{
particle p;
p.mass = 10;
p.x = 0;
p.y = 100;
p.z = 0;
p.dx = 0;
p.dy = 0;
p.dz = 0;
p.forces.push_back(gravity);
p.forces.push_back(resistance);
}
If you're going to be dealing with three dimensional forces, you'll probably want more information in the return type than just a double, but this should be a good starting point. Also, if you have a c++11 compatible compiler, you may also want to lookup lambda functions so that the functions can be created in the same line.
You can use std::function. Something like this:
// define a type for the function
typedef std::function< void(particle const&, float *fxfyfz) > forcer_function;
std::vector< forcer_function > forces;
Now, some words with regards to performance. Since this is particles you're talking about, I'm assuming that you have a reasonably large number of particles (eg some hundreds at least). So I'm assuming that you have an interest in getting this code to run moderately fast.
So, first, using std::list for your container is not advised due to bad cache properties. It will make your code much slower. Therefore, the use of std::vector.
Second, adding the list of forces as a member of your particle structure is uncommon. Do you really want to use different forces per particle? Typically, there are <5 forces and >100-1000 particles. If you can use the same collection of forces for all of your particles, then moving the forces out of your particle class will give you a gain. For example,
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
};
struct particle_container
{
std::vector< particle > particles;
std::vector< forcer_function > forces;
void update();
};
void particle_container::update()
{
for(particle &p : particles) {
double rx, ry, rz;
rx = ry = rz = 0.0;
for(forcer_function fn : forces) {
double f[3];
fn(p, &f[0]);
rx += f[0];
ry += f[1];
rz += f[2];
}
// integrate resulting force, etc
// ...
}
}
If OTOH you really want to use per-particle forces, you can still use the approach I outlined above by grouping particles with the same force collection in different container objects. Then you can reuse all of the above, and adding one more class will fix it:
struct particle_groups
{
std::vector< particle_container > groups;
void update();
};
void particle_groups::update()
{
for(auto &g : groups) {
g.update();
}
};
If you really, really, want no grouping, then at least consider whether there's a way you can use particle members zeroing out inactive forces. Then you could still use the approach above. For example, like this:
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
// is gravity active? either 1.0 or 0.0
double grav;
// is player interaction active? either 1.0 or 0.0
double player;
// etc... for all possible forces
};
Then just multiply eg, your resulting gravity by the particle's grav member, and you effectively switch gravity off or on for that particle, according to whether particle.grav's value is 1.0 or 0.0.
Finally, std::function is slow. You can use a mix of the two approaches above and use a single function. Like this:
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
};
struct force_settings
{
double grav;
double attractor;
double player;
//etc...
};
struct particle_container
{
// no need to keep pointers to functions
force_settings forces;
std::vector< particle > particles;
void update();
void compute_forces(particle const& p, double *rf) const
{
// zero resulting force
rf[0] = rf[1] = rf[2] = 0.0;
// compute gravity, (assume y axis)
rf[1] += forces.grav * 9.8; // will be either 9.8 or 0.0
// compute attractor
double ax = p.x - attractor.x;
double ay = p.y - attractor.y;
double az = p.z - attractor.z;
rf[0] += forces.attraction * ax*ax;
rf[1] += forces.attraction * ay*ay;
rf[2] += forces.attraction * az*az;
// etc... more forces here
}
};
void particle_container::update()
{
for(particle &p : particles) {
double rf[3];
compute_forces(p, &rf);
// integrate, etc...
}
}

Is it possible to declare a 2d array class member inside the constructor with a for loop?

Currently I have this
//gameboard.h
class GameBoard
{
public:
GameBoard(bool showShips);
~GameBoard();
void draw();
void placeShipStart(int x, int y);
void placeShipEnd(int ship, int x, int y);
private:
bool defaultShowShips;
Field playerBoard[10][10];
vector<Ship*> ships[5];
};
//gameboard.cpp
GameBoard::GameBoard(bool showShips)
{
defaultShowShips = showShips;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
xyzCoord ul, lr;
ul.x = j * 5.0f;
ul.y = i * 5.0f;
ul.z = 2.0f;
lr.x = j * 5.0f + 5.0f;
lr.y = i * 5.0f + 5.0f;
lr.z = 0.0f;
playerBoard[i][j] = Field(ul, lr);
}
};
The way it is right now it's telling me that I need to have a default constructor for field. I'm trying to accomplish initializing each position in a different position. Am I doing this completely wrong? I've seen the vector of vectors approach. If possible I would like to avoid that because it wasn't working for me earlier.
I am guessing here to a certain degree, but try this:
Field::Field()
{
// Provided default values to your two member variables
}
Field::Field(xyzCoord ul, xyzCoord lr)
{
// Populate your two member variables with the passed in values
}
The first constructor will be your default as it has no parameters.
I hope this helps. Apologies if I miss-understood your question.
Update
The alternative is:
This in the header:
Field::Field(xyzCoord ul = xyzCoord(), xyzCoord lr = xyzCoord())
This in the source:
Field::Field(xyzCoord ul /*xyzCoord()*/, xyzCoord lr /*xyzCoord()*/)
{
// Populate your two member variables with the passed in values
}
I am conveying the principles. Without seeing the Field and xyzCoord class I can't see what the suitable declarations would be. With this last approach the constructor how provides default values for each parameter.
See this default constructor topic for more information. In part it mentions:

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.