Arrange particles in the shape of a rectangle - c++

I have a particle simulation program I'm currently working on that generate random particle positions in a rectangular shape. This works for now but it's not the best solution, often particles overlap and there are small holes in the rectangle. How would I initialize the particles in the shape of a rectangle?
My current loop:
for(auto i=0; i<MAXPARTICLES; i++){
int particleIndex = FindUnusedParticle(); //grab the index to give a particle life
ParticlesContainer[particleIndex].life = 100.0f; //Long particle life
//generate random positions for particles in the shape of a box with random patterns
ParticlesContainer[particleIndex].pos = glm::vec3((rand()%50)/5.0,(rand()%50)/5.0,-50.0);
// Very bad way to generate a random color
ParticlesContainer[particleIndex].r = 255;
ParticlesContainer[particleIndex].g = 0;
ParticlesContainer[particleIndex].b = 0;
ParticlesContainer[particleIndex].a = 255;
ParticlesContainer[particleIndex].size = .2f;
}

It's a more complicated problem than just using uniform distribution over two dimensions separately. If your "evenliness" is the distance between two closest particles, then there are exactly two ways to achieve that: equilateral triangles and squares (well, three if you count hexagons). The only random thing there is the position of one seed and the "direction" in which that will go.
Refer to the image:
That will give you a very regular, grid-like look, though. You could try applying random, minuscule changes to particles distributed that way, and see how that would work.

Related

Adding graphs together in c++ (to generate fractal noise)

I am trying to make a 1D fractal noise function. I have a function generating every single individual graph, but am struggling with how to add them together. I am following this tutorial
https://web.archive.org/web/20160530124230/http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
Here is my code for my final noise function
(I am using sfml, which is what the sf::vector2f are. It's just a vector of two floats, representing a coordinate.)
void fractalNoise() {
std::vector<sf::Vector2f> allGraphs;
std::vector<sf::Vector2f> singleNoise;
float persistance = 0.8; //represents the decrease of amplitude with frequency.
//The closer to one, the less the amplitude decreases each iteration
int nOOPM1 = 10; //number of iterations
for (int i = 0; i < nOOPM1; i++) {
float frequency = pow(2, i);
float amplitude = pow(persistance, I);
//generate a random plots of noise, equidistant on the x, and random on the Y.
//the 3 is the interpolation method(ignore this), and the 1000 is how many points to draw
singleNoise = this->interpolateNoise(
this->generateNoise(frequency, 300 * amplitude), 3, 1000);
between each point.
allGraphs.insert(allGraphs.end(), singleNoise.begin(), singleNoise.end());
}
this->noiseGenerated = allGraphs;
//every pixel stored in noiseGenerated is rendered to a window
};
I understand that the allGraphs.insert is just putting the next graph after the current one, but I am unsure how to add each graph together. Because of the nature of fractal noise, and the fact my frequencies are always changing, I can't just add the noise points before interpolating them, as they will mostly have different x values
Any help would be appreciated

Draw (2D) Polygon with given 3D-Vertices and Transformation with VTK

I have some 3d models and I want to display each face of the model seperately. For each face, I have a list of the vertices (as pcl::PointCloud), the Translation vector (as Eigen::Vector3f) and the Rotation Matrix (as Eigen::Quaternionf). The faces can have different shapes. It will be rectangular, round (n-verts polygon) and trapezial.
For the rectangular faces, I used vtkCubeSource so far and it works good. For the round faces, I could maybe use vtkCylinderSource. For trapezial faces, I didn't found a solution so far.
The best would be a class like vtkPolyLineSource, where I just need a list of vertices for any polygons. But as far as I see, vtkPolyLineSource would just draw the the line and don't fill the polynom with a color.
Is there a way to draw a polygon into 3d-space with vtk? Since it is possible to directly draw a 3d-model from a file, I think there should be a method for drawing a model (or just one face), but I couldn't find it so far. That's my first contact with VTK, so I think I just overlooked the right classes.
One reason why I don't just load a model-file is, that I need the faces in different colors and opacitys (defiend at runtime).
Use vtkPolygon
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
// ... fill in your points with n points
// Create the polygon
vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
polygon->GetPointIds()->SetNumberOfIds(n);
for (int j = 0; j < n; j++)
{
polygon->GetPointIds()->SetId(j, j);
}
// Add the polygon to a list of polygons
vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
polygons->InsertNextCell(polygon);
// Create a PolyData
vtkPolyData* polygonPolyData = vtkPolyData::New();
polygonPolyData->SetPoints(points);
polygonPolyData->SetPolys(polygons);
// create mapper and actor using this polydata - the usual stuff

Generating discrete vectors in a difference of cubes space

I want to generate random discrete valued vectors in a space. The simple instance was a follows; a cube. In this instance each coefficient of the vector had to be in between two values, so that it is inside the multi-dimensional cube. This cube can be described by it's two corner points (stored in points[0] and points[1]). I programmed this in C++(11) as follows:
random_device rd;
mt19937 eng(rd());
vector<uniform_int_distribution<>> distr;
for(int i = 0; i< points[0].size();i++){
distr.push_back(uniform_int_distribution<>(point[0].at(i),points[1].at(i)));
}
for(int i = 0;i<trials;i++){
vector<unsigned> draw;
for(int j = 0; j< points[0].size();j++){
draw.push_back(distr.at(j)(eng));
}
// Do stuff with vector
}
This code runs fine. Now however instead of a cube, I have to generate a vector inside the difference of two cubes. So we have the two corner points of the large cube, and a point inside the large cube that combined with EITHER the top OR bottom corner of the large cube induces a cube in which I don't want the vector to lie.
My first instinct was to generate vectors as before and then filtering out those that are in the small cube. If however the small cube is rather large, then it will take too much time to generate the amount of trials I want. Does someone here have an idea?
I think that first you need to define what that third point is, i.e.: say that your initial cube is (point[0],point[1]) and that the third point is point[2]. Do you want to sample in the difference between (point[0],point[1]) and (point[0],point[2]) or in the difference between (point[0],point[1]) and (point[2],point[1])?
Accordingly, I would change the call to the ctor uniform_int_distribution<>(point[0].at(i),points[1].at(i))) to uniform_int_distribution<>(point[2].at(i),points[1].at(i))) or to uniform_int_distribution<>(point[0].at(i),points[2].at(i))).

Brute force collision detection for two objects too slow

I have a project to see if two objects (made of about 10,000 triangles each) collide using the brute force collision algorithm, rendered in OpenGL. The two objects are not moving. I will have to translate them to some positions and find e.g. 100 triangle collisions etc.
So far I have written a code that actually checks for line-plane intersection between these two models. If I got everything straight I need to check every edge of every triangle of the first model with the each plane of each triangle of the other model. This actually means 3 'for' loops that take hours to end. I suppose I must have something wrong or got the whole concept misunderstood.
for (int i=0; i<model1_faces.num; i++) {
for (int j=0; j<3; j++) {
x1[j] = model1_vertices[model1_faces[i].v[j]-1].x;
y1[j] = model1_vertices[model1_faces[i].v[j]-1].y;
z1[j] = model1_vertices[model1_faces[i].v[j]-1].z;
}
A.x = x1[0];
A.y = y1[0];
A.z = z1[0];
B.x = x1[1];
B.y = y1[1];
B.z = z1[1];
C.x = x1[2];
C.y = y1[2];
C.z = z1[2];
TriangleNormal = findNormalVector((B-A)*(C-A));
RayDirection = B-A;
for (int j=0; j<model2_faces.num; j++) {
PointOnPlane = model2_vertices[model2_faces[j].v[0]-1]; // Any point of the triangle
system("PAUSE");
float D1 = (A-PointOnPlane)^(TriangleNormal); // Distance from A to the plane of j triangle
float D2 = (B-PointOnPlane)^(TriangleNormal);
if ((D1*D2) >= 0) continue; // Line AB doesn't cross the triangle
if (D1==D2) continue; // Line parallel to the plane
CollisionVect = A + (RayDirection) * (-D1/(D2-D1));
Vector temp;
temp = TriangleNormal*(RayDirection);
if (temp^(CollisionVect-A) < 0) continue;
temp = TriangleNormal*(C-B);
if (temp^(CollisionVect-B) < 0) continue;
temp = TriangleNormal*(A-C);
if (temp^(CollisionVect-A) < 0) continue;
// If I reach this point I had a collision //
cout << "Had collision!!" << endl;
Also I do not know exactly where exactly should this function above be called. In my render function so that it runs continuously while rendering or just once, given the fact that I only need to check for a non-moving objects collision?
I would appreciate some explanation and if you're too busy or bored to see my code, just help me with understanding a bit more this whole concept.
As suggested already, you can use bounding volumes. To make best use of these, you can arrange your bounding volumes in an Octree, in which case the volumes are boxes.
At the outermost level, each bounding volume contains the entire object. So you can test whether the two objects might intersect by comparing their zero-level bounding volumes. Testing for intersection of two boxes where all the faces are axis-aligned is trivial.
The octree will index which faces belong to which subdivisions of the bounding volume. So some faces will of course belong to more than one volume and may be tested multiple times.
The benefit is you can prune away many of the brute-force tests that are guaranteed to fail by the fact that only a handful of your subvolumes will actually intersect. The actual intersection testing is of still brute-force, but is on a small subset of faces.
Brute force collision detection often does not scale, as you have noticed. :) The usual approach is to define a bounding volume that contains your models/shapes and simplifies the intersection calculations. Bounding volumes come in all shapes and sizes depending on your models. They can be spheres, boxes, etc.
In addition to defining bounding volumes, you'll want to detect collision in your update section of code, where you are most likely passing in some delta time. That delta time is often needed to determine how far objects need to move and if a collision occurred in that timeframe.

uniform sampling of a 3D model

I seek for a method/algorithm for uniform sampling of the surface of 3D models in C++.
I have found methods for uniform sampling of unit sphere such as
this and this but I need something that would work also for more complex 3D models that may also be concave.
thanks in advance
What I do: My model consists of many different primitives (triangles, quads, disks, cylinder...). For each primitive I can implement a random picking method (e.g. http://mathworld.wolfram.com/TrianglePointPicking.html). Each primitve can compute its surface Area. The higher the area of the primitive the higher its probability to generate a random point. In my model I build a cumulative list like this
class Model{
// ...
vector<pair<double, Primitive*> > primitives_;
}
void Model::AddPrimitive(Primitive* p)
{
double area = p->Area();
if (!primitves_.empty())
area += primitives_.back().first;
primitives_.push_back(make_pair(area, p));
}
When I generate a random point on the model I first choose a random primitive and then a random point on this primitive.
Point Model::RandomPoint()
{
double maxArea = primitives_.back().first;
double rnd = maxArea * Uniform01(); // random in [0; maxArea]
Iterator it = std::lower_bound(
primitives_.begin(), primitives_.end(), rnd, FirstLess());
return it->second->RandomPoint();
}