3d array with negative index - c++ - c++

I need a 3 dimensional array which supports negative indices.
Something similar to boost::multi_array, where I could specify bounds for each dimension, ie:
int xMin = -5; int xMax = 7;
int yMin = 3; int yMax = 10;
int zMin = -8; int zMax = -2;
SuperArray<float> ar;
ar.setBounds(xMin, xMax, yMin, yMax, zMin, zMax);
ar[-3][5][-5] = 1.0f;
Basically, it's indexing voxel subspace in 3D :)
Is there anything ready outthere, or am I to create this by myself ?
thanks !

Why don't you just do a translation?
Lets say the array size is:
d1 = 100
d2 = 100
d3 = 100
[d1][d2][d3]
// where index 0 = -50 and index 99 = 50
//Pseudo code
// x = -1; y = 2; z = 2;
value = array[d1/2+x][d2/2 + y][d3/2 +z];

Set the size of each dimension to Max-Min. Then when you want to access an array element, add -Min to each index. So for your dimensions, you would declare:
float ar[12][7][6];
Then to access the element you want, you do:
ar[-3-(-5)][5-3][-5-(-8)] = 1.0f;
You should be able to write a class that hides all these transformations (which is what the Boost library is doing).

Related

Spherical Coordinate Mapping creating double epsilons

Here is an image: http://i.imgur.com/MRvz24u.gif
So I can tell what the problem is, that my epsilon (or whatever that symbol is) used for spherical coordinates are repeating. So the way I calculate the points is:
double theta = acos(p.getY()/p.magnitude());
theta = theta/3.1415926;
double epsilon = atan(p.getZ()/p.getX());
epsilon = epsilon + 3.1415926/2;
epsilon = epsilon /3.1415926;
I'm pretty sure the rest isn't the problem but I will put it here just in case
int w = texture ->columns();
int h = texture ->rows();
double x = w * epsilon ; x = (int) x;
double y = h * theta; y = (int) y;
int row = y;
int column = x;
Magick::PixelPacket *pixels = texture->getPixels(0, 0, w, h);
Magick::Color color = pixels[w * row + column];
double range = pow(2, texture -> modulusDepth());
double r = color.redQuantum()/range ;
double g = color.greenQuantum()/range ;
double b = color.blueQuantum()/range ;
return Color(r, g, b, 0);
I am not sure why I would be getting repeating values because my range should originally be -pi/2 < epsilon < pi/2 and I just shift it then scale it.
Use atan2 instead of atan. atan accepts x/y while atan2 accepts x,y .
This allows atan2 handle the case where x and y are both negative differently from the case where they're positive. atan has no way of knowing.

interior angles of irregular polygon with angles > 180

I'm trying to calculate the values shown in the picture in red i.e. the interior angles.
I've got an array of the points where lines intersect and have tried using the dot-product but it only returns the smallest angles. I need the full range of internal angles (0-359) but can't seem to find much that meets this criteria.
Assuming your angles are in standard counterclockwise format, the following should work:
void angles(double points[][2], double angles[], int npoints){
for(int i = 0; i < npoints; i++){
int last = (i - 1 + npoints) % npoints;
int next = (i + 1) % npoints;
double x1 = points[i][0] - points[last][0];
double y1 = points[i][1] - points[last][1];
double x2 = points[next][0] - points[i][0];
double y2 = points[next][1] - points[i][1];
double theta1 = atan2(y1, x1)*180/3.1415926358979323;
double theta2 = atan2(y2, x2)*180/3.1415926358979323;
angles[i] = (180 + theta1 - theta2 + 360);
while(angles[i]>360)angles[i]-=360;
}
}
Obviously, if you are using some sort of data structure for your points, you will want to replace double points[][2] and references to it with references to your data structure.
You can obtain full angle range (-Pi..Pi) with atan2 function:
atan2(crossproduct, dotproduct)

Linear interpolation code on wikipedia - I don't understand it

I'm reading the following code (taken from here)
void linear_interpolation_CPU(float2* result, float2* data,
float* x_out, int M, int N) {
float a;
for(int j = 0; j < N; j++) {
int k = floorf(x_out[j]);
a = x_out[j] - floorf(x_out[j]);
result[j].x = a*data[k+1].x + (-data[k].x*a + data[k].x);
result[j].y = a*data[k+1].y + (-data[k].y*a + data[k].y);
}
}
but I don't get it.
Why isn't the result[y] calculated by using the
formula?
It is calculated that way.
Look at the first two lines:
int k = floorf(x_out[j]);
a = x_out[j] - floorf(x_out[j]);
The first line defines x0 using the floor function. This is because the article assumes a lattice spacing of one for the sample points, as per the line:
the samples are obtained on the 0,1,...,M lattice
Now we could rewrite the second line for clarity as:
a = x_out[j] - k;
The second line is therefore x-x0.
Now, let us examine the equation:
result[j].y = a*data[k+1].y + (-data[k].y*a + data[k].y);
Rewriting this in terms of y, x, and x0 gives:
y = (x-x0)*data[k+1].y + (-data[k].y*(x-x0) + data[k].y);
Let's rename data[k+1].y as y1 and data[k].y as y0:
y = (x-x0)*y1 + (-y0*(x-x0) + y0);
Let's rearrange this by pulling out x-x0:
y = (x-x0)*(y1-y0) + y0;
And rearrange again:
y = y0 + (y1-y0)*(x-x0);
Again, the lattice spacing is important:
the samples are obtained on the 0,1,...,M lattice
Thus, x1-x0 is always 1. If we put it back in, we get
y = y0 + (y1-y0)*(x-x0)/(x1-x0);
Which is just the equation you were looking for.
Granted, it's ridiculous that the code is not written so as to make that apparent.

How to map a 2D array in a 1D array in C++?

Lets say, I have a MxN arrays: int *b; and int **c; where
values in b are stored by columns (from c) and I need to put values
from c to b
values in b are stored by rows (from c) and I need to put values
from c to b
I know that basicly I would do it like that:
j = index / N;
i = index - (j * M);
in order to convert a 1D index into a 2D co-ordinate but have a problem
how to implement those 2 cases, 1) and 2)?
Let W be the width of the 2D array, and H its height. Then assuming row-major layout, the 1D index 'ix' relates to the 2D-index [x,y] as such:
ix = y*w + x;
y = ix / w; // implicit floor
x = ix % w;
e.g.:
const int W = 3, H=2;
int m[H][W] = {{1,2,3}, {4,5,6}};
int* oneD = &m[0][0];
assert(oneD[1*W + 2] == m[1][2]); // element 6, y=1, x=2

How do I draw a cylinder in OpenTK(.Glu.Cylinder)?

How do I draw a cylinder with OpenGL in OpenTK?
Sample code from an older project of mine. This creates an "uncapped" cylinder (top and bottom are empty).
int segments = 10; // Higher numbers improve quality
int radius = 3; // The radius (width) of the cylinder
int height = 10; // The height of the cylinder
var vertices = new List<Vector3>();
for (double y = 0; y < 2; y++)
{
for (double x = 0; x < segments; x++)
{
double theta = (x / (segments - 1)) * 2 * Math.PI;
vertices.Add(new Vector3()
{
X = (float)(radius * Math.Cos(theta)),
Y = (float)(height * y),
Z = (float)(radius * Math.Sin(theta)),
});
}
}
var indices = new List<int>();
for (int x = 0; x < segments - 1; x++)
{
indices.Add(x);
indices.Add(x + segments);
indices.Add(X + segments + 1);
indices.Add(x + segments + 1);
indices.Add(x + 1);
indices.Add(x);
}
You can now render the cylinder like this:
GL.Begin(BeginMode.Triangles);
foreach (int index in indices)
GL.Vertex3(vertices[index]);
GL.End();
You can also upload vertices and indices into a vertex buffer object to improve performance.
Generating the geometry for a cylinder is quite simple (let's consider a Z-aligned cylinder). Let me use pseudocode:
points = list of (x,y,z)
where x = sin(a)*RADIUS, y = cos(a)*RADIUS, z = b,
for each a in [0..2*PI) with step StepA,
for each b in [0..HEIGHT] with step StepB
About the indices: Let us assume N equal to the number of "levels" or "slices" of the cylinder (which depends on HEIGHT and StepB) and M equal to the number of points on every "slice" (which depends on StepA).
The cylinder contains some quads, each spanning 2 neighbouring slices, so the indices would look like:
indices = list of (a,b,c,d)
where a = M * slice + point,
b = M * slice + (point+1) % M,
c = (M+1) * slice + (point+1) % M,
d = (M+1) * slice + point
for each slice in [0..N-2]
for each point in [0..M-1]
If you need normals for the cylinder, they are simple to generate:
normals = (x/RADIUS,y/RADIUS,0)
for each (x,y,z) in points
That's it for the round part of the cylinder, you might also want the "caps" but I believe they are easy to do.
I'll leave the fun part of translating my pseudocode into your language of choice for you. :)
The rest is to create/bind the VBO, load up the geometry, set pointers, use your shader of choice and call glDrawArrays(...) - any OpenGL 3 tutorial should cover this; are you familiar with that part?