Hi I have a question about the use of vectors in in c++, I am working on a problem of simulating particle movement through containers by random motion. I have a need for adding and removing particles as they meet or fail to meet certain criterion and for this purpose I found the vector class very handy, however I am new to c++ and a have a problem of efficiency I need to consider.
Are the 2D arrays I define limited to being either rectangles or squares? I only need to store the position of particles in each container. What I am afraid of is that my matrix will look like this:
| | | | |
| | | | |
| | | | |
| | | | |
for the 4x4 case. With the entry of the column being the position of the particles in each bin/container and number of particles differing from bin to bin I wonder if something like this is possible:
| | | | | 4 particles in first bin
| | | 2 particles in second bin, the memory occupied being 2x less than the one above
| | | | | | | | | | | | | | | | | this many in third bin and so on.
I will also be needing to remove elements in rows (reducing row size) or adding elements in rows (increasing row size) or in columns depending on which way I implement my algo and would appreciate it if you could warn me beforehand if there are common mistakes when dealing with vectors of multiple dimensions as I am sure to make one, being new to the programming language :)
You can use a vector of vectors: vector<vector<Particle> >
At first, when you ask about "2D arrays ... limited to ... rectangles or squares" it sounds like you are asking how to represent "jagged" arrays (arrays that are not rectangular, but have a fixed "height", with a variable "width" per-row).
But "tetris" shapes (tetraminos) don't lend themselves particularly to jagged arrays. It makes me think you actually want a sparse array. That is, you'd like to store only positions of particles, and not store positions of non-particles.
The easiest way to do this is to simply skip the grid, and directly maintain a list of positions of occupied spaces/particles.
struct Position
{
float X;
float Y;
};
// ...
std::vector<Position> particles; // std::list works too...
But plain lists aren't very efficient for some purposes. If you need to have spatially indexed access to these, for example to find out how many particles are in a given volume/area within your simulation, then you should use a space partitioning data structure that still allows sparse population.
People commonly do this the way you are describing, with a rectangular grid, then storing a list inside each grid location of the particles contained in that grid cell. But that "wastes space" for grid cells that aren't used. It doesn't solve the sparse population problem.
A popular data structure that supports both spatial indexing and sparse population is a quadtree.
Related
Would like to apologise if this is too maths based.
I have a project where I have to create an AngryBirds game with our teacher's custom game engine, however I am stuck on the maths behind the slingshot. We are not allowed to use any standard libraries. The top left is 0, 0 and the y-axis increases when you go down. The total width of the window is 1280 pixels and the height is 720 pixels. I am trying to make the bird travel further as you pull the bird further left from the sling origin which is 257, 524. I used the y value from release at the start so that the bird doesn't go somewhere else in the y-axis straight after letting go. Currently the bird increases in the y-axis, which is to be expected given that is exactly what my code does. I created a variable determining how far from the origin of the slingshot the bird is once the mouse has been let go and I would like to use this value in a speed calculation. I don't know what values to use in a quadratic formula to make the bird stay on the screen. I have tried to illustrate the window to make it clearer.
float y = getY() + getX()/10 * getX()/10 * (game_time.delta.count() / 10000.f);
setY(y);
//window illustration
------------------------------------------------------------------------------
| (0, 0) |
| |
| |
| o o |
| o |
| o o |
| |
|bird-> o\ / (257, 524) o |
| | |
|_________|______________________________________________________(1280, 720)_|
You have two problems:
lack of knowledge of elementary physics, related to an oblique shot.
window origin being in top-left corner implies left the coordinate system.
For the first part, I'd suggest you read some article about an oblique shot physics, like kinematics of projectile motion.
In brief:
divide the bird motion into horizontal and vertical parts:
horizontal part is the motion with constant speed
vertical motion is the motion influenced by the constant force
calculate horizontal and vertical components of velocity & position independently as a function of time
use calculated position to draw the "bird"
The second problem is easily solved by placing your coordinate system into the lower left part of the window, with y pointing up. This way you have a "right-hand" coordinate system that will be used for all calculations using equations found on the aforementioned link.
When you need to actually 'draw' the bird, use the following transformation for y coordinate:
y_draw = window_height - y_calculated;
Don't forget to add appropriate offsets for x and y to compensate for the fact that the origin for calculus is different from the position of the slingshot.
For an Visual Studio developed OpenGL Game, is there any possibility to count the Triangles or Objects (meshes without connection to each other) that are drawn with the help of the API? I did not find any information on that. Counting them manually seems artificially painful.
While it isn't really a hassle to do it "yourself", you could override/redirect all glDraw*() calls.
I did something similar a few years ago, where I wanted to count the amount of draw calls any given frame made (for debug builds). I implemented it by having a macro for each glDraw*(). Which looked like:
int drawCallCount = 0;
#define glDrawArrays(...) \
do { glad_glDrawArrays(__VA_ARGS__); ++drawCallCount; } while (0)
// etc glDraw*()
Then at the end of each frame I would read drawCallCount and reset it back to 0.
Note that I was/am using GLAD.
Considering glDrawArrays(GLenum mode, GLint first, GLsizei count). Then you would check if mode is GL_TRIANGLES then (count - first) / 3 would be the amount of triangles that draw call made.
+-------------------+---------------------+
| Mode | Triangles |
+-------------------+---------------------+
| GL_TRIANGLES | (count - first) / 3 |
+-------------------+---------------------+
| GL_TRIANGLE_STRIP | (count - 2 - first) |
+-------------------+---------------------+
| GL_TRIANGLE_FAN | (count - 2 - first) |
+-------------------+---------------------+
I figured it out myself, and the result is exactly the same as in blender.
The drawn objects have of course a lot of meshes. The drawn mesh vertex count stored in a simple variable which set to zero and afterwards summed up and divided by three on each render loop iteration.
so I have this class:
class Piece{
int width;
int height;
}
my problem is that I need to make a container type class that somehow can save the layout of multiple and different size "Piece" objects (note that Piece can only represent rectangles).
Example:
________
| t |
| t jj |
| t jj |
_________
My goal with this is to be able to "fill" a empty rectangle with multiple "Piece" objects but with the ability to know if the "Piece" can fit in.
I'm developing this in C++. I started with the most logic solution I think that was to use a "matrix" of vectors (vector< vector< Piece * > > mat) but that doesn't work because as I said "Piece" objects can have different sizes.
I hope you can give some hints on how to get a solution for this or if it exists some lib or open-sorce project links.
Thank you.
EDIT
I forgot this:I know beforehand the dimensions of the container and the insertion (after validation) is sequential (Piece after Piece) with no predefined orientation.
You can use Piece p[width][height] and use memset to make all zeros or use a std::vector if you don't know the size of the grid beforehand. Then you can check(while adding a new Piece at some position (x, y)) if on any of its subsquares there is some other Piece already.
Edit: You can use a matrix char mem[sqrt(width)][sqrt(height)]; and a one vector of Pieces. Then using the matrix if there will be a probable collision and if not, just add the Piece. Else you iterate through all the existing ones and check for a collision.
If you want to make the procedure faster( this one is reasonable only with small grids ), then you will need to use more "advanced" data structures. What I suggest you is to learn about 2D BIT(or fenwick) trees(there are a lot of resources on google). You can also use 2D segment trees. Then when adding a new Piece at position (x, y) check the sum of all squares in it(e.g from (x, y) to (x + width, y + height)). If that sum is zero then the new Piece won't collide with previous ones and you then update the grid as you add 1 to all squares in your Piece(I mean to the corresponding values in the 2D segment tree). Else if the sum is greater than zero it means that there will be some overlap and you must then discard the new Piece.
I have developed an OpenGL project using the old GL_QUADS rendering, not using Shaders.
I want to average the colours of mine radiosity solution. I have a number of patches per face. What I did:
I average the colours of the adjacent patches within a face. I got good results but still getting some mach band effect.
Ill try to explain what I did:
// ___________________
// |v3 v2|v3 v2|
// | | |
// | | |
// | 2 | 3 |
// | | |
// |v0_____v1|v0_____v1|
// |v3 v2|v3 v2|
// | | |
// | | |
// | 0 | 1 |
// | | |
// |v0_____v1|v0_____v1|
every patch has a colour. Patch 0, patch 1, patch 2 and patch 3. The vertices of that patch are the same of the patch colour. Then I change the vertices colours by averaging the colours with adjacent patches. So at first, I get the colour of patch 0 and 1, add them together then divide by 2, then I set this new colour to the vertex 1 of patch 0 and vertex 0 of patch 1.
However, I saw a paper where they get different results.
On this image, he sort of tried to explain how he got those values. But I didn't understand. He is doing something very similar from what I did, but I think he does get rid of match band effects.
I get results like this:
This is the results I get with my Radiosity rendering:
This is the results I get with my interpolation method:
It did got more smooth, but I still have huge mach band effects
I do not understand what the figure 8a is trying to accomplish, but your implementation sounds reasonable to me.
The artifacts you see are not a problem of you interpolation but due to the fact that you have a low-contrast color gradient on a flat surface.
If for example RGB color changes from (100,0,0) to (110,0,0) over 100 pixel, then every ten pixels you have change in color by 1 in the red channel. As your scene is very simple these edges extend over larger parts of the image. The human brain is very good at detecting them, so voila.
Probably the only way around would be to use a more complex scene, to use textures or to use a fragement-shader with some artificial small noise.
I'm trying to create a randomized maze in C++, but I can't start because I don't know how to create grids or cells. How could I create it? And I also want to create it using ASCII characters. how can i store it in array? (can any one give a sample code and some explanation so i can understand it better)
Another question: What data stuctures should I need to learn and use? I'm planning to use Eller's algorithm or Kruskal's algorithm.
Thank you guys for helping me! im a begginer programmer, and i want to learn about this, because this is a part of my project, thank you vary much!
Are you looking for Maze generation algorithms (more)? Is your problem with the algorithms, or graphics?
The typical algorithms work by considering each "cell" in the maze as a vertex of a graph, start with all "walls", and remove a set of walls that corresponds to a spanning tree. (So in order to randomize it, many of them start with random weights and find the minimum spanning tree.) For small mazes at least, you don't need any special data structure to represent the cells; you can just think of each cell as a pair (x,y) (its coördinates). And you don't need any data structure (adjacency matrix / adjacency list) to store the edges of the graph either, because the neighbours of (x,y) are just (x,y±1) and (x±1,y) (ignoring those that fall outside the boundaries).
In any case, once you have the spanning tree, you know exactly which of the walls "exist" and which do not, so you have a complete description of the maze. If you're going to draw the maze, you know which ones to draw.
To draw with ASCII characters, you just pass through each row one by one: draw the "upper walls" (put a "--" if the wall between (x,y) and (x,y+1) exists), then draw the actual row (put a "|" if the wall between (x,y) and (x+1,y) exists). Finally draw the bottom boundary.
You probably want to store your maze in a 2-dimension char array. You can declare an array with or without initializing it in C++.
char a[30][10]; // declares a char array of 30 rows and 10 columns.
// declare an array with 3 rows and 3 columns, and provide initial values
char ticTacToeBoard[3][3] = {{'x', 'x', 'o'},
{'o', 'o', 'x'},
{'x', 'o', ' '}
};
You could change the initial values to '|' and '-' for walls in your maze, and use a space character, ' ', for the passageways.
Either initialization method works, but you always use the elements the same way. Here's how you clear the board in the initialized array above.
// clear the board
for (int row=0; row<3; row++) {
for (int col=0; col<3; col++) {
ticTacToeBoard[row][col] = ' ';
}
}
If you want to read the value of an element (useful when you're trying to navigate a maze), you use the same subscript notation as when you're setting its value.
char y = a[2][2]; // reads the character in row 2, column 2
Vertical Wall: |
Horiz. Wall: _
If you're using fixed-width fonts:
_____
| | _
|_ | |
__ | |
|_____|
I'm not sure exactly what to do, but here's where I'd start.
Determine where on your grid the start and end points will be. Then, create a single path, with whatever squiggles you want. Basically, it should be random movement, checking each time that there is still a way for this path to reach the end. Then, remove a certain amount of walls from this path, and create other paths from these holes. Continue this until you run out of empty space. Then, perhaps, ensure that no shorter paths have been created. If they have, block those up.