0

EDIT: I reformulate the question simply: How do I generate in C++ or Python, random points (x,y) following: a circular distribution, a square distribution, and a triangular distribution.

This is a simple code for square for example:

def generateSquare(min, max, size):
    data = []

    for i in range(size):
        x = randint(min, max)
        y = randint(min, max)
        data += [[x, y]]

    return data
Amro
  • 123,847
  • 25
  • 243
  • 454
shn
  • 5,116
  • 9
  • 34
  • 62
  • 1
    Is this a complicated way to ask "how can I generate random numbers" ? – PlasmaHH Jun 19 '12 at 11:54
  • 1
    Why not just randomly generate the centroid of each item, and then pass that centroid to a `draw_cross` function? Do you really need to know the actual arcs that make up each decoration in the cloud? – Rook Jun 19 '12 at 11:54
  • @PlasmaHH that not a generation of random numbers ... I want to generate 2D data following some forms – shn Jun 19 '12 at 12:13
  • 1
    @user995434: This still seems to boil down to me for a question on how to generate random numbers, just with a certain distribution... – PlasmaHH Jun 19 '12 at 12:15
  • @Rook I didn't understand what you said. Can you explain this by a code ? I understand source code better than sentences. – shn Jun 19 '12 at 12:38
  • 1
    You basically want to draw a random point cloud where all the points lie within some geometric region on the plane, right? You shoudl use Luc's solution below, only with an additional step that simply rejects any point that doesn't fall within the specified region. Seems simple enough. – Rook Jun 19 '12 at 12:52
  • Do you know the coordinates of the geometric region where you want your shaped cloud to be, or should that be random too? – Luc Touraille Jun 19 '12 at 13:10
  • @Rook how do you define the specific region, this is the question ! Because just generating some random points on the plan is indeed easy. And if you know how to define the specific region (that forms a cycle for example) you will be able to just generate points within this region, instead of doing as you suggested. – shn Jun 19 '12 at 13:11
  • @LucTouraille the coordinate can be parameters specified by the user, or random, this is not a problem. – shn Jun 19 '12 at 13:12
  • @user995434: Hum, no, generating random points within a specific region is probably not as simple as you think it is (except for trivial cases such as a square), whereas testing if a random point is in a given region (and rejecting it if it's not) should be much more simple. – Luc Touraille Jun 19 '12 at 13:13
  • @LucTouraille well how will you code that ? – shn Jun 19 '12 at 13:15
  • For a very generic answer, see [this question about hit-testing](http://stackoverflow.com/questions/217578/point-in-polygon-aka-hit-test). For circles, see [this](http://stackoverflow.com/questions/481144/equation-for-testing-if-a-point-is-inside-a-circle). Square is easy (well, [unless it is rotated](http://www.emanueleferonato.com/2012/03/09/algorithm-to-determine-if-a-point-is-inside-a-square-with-mathematics-no-hit-test-involved/)). For triangles, see [this](http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-triangle). – Luc Touraille Jun 19 '12 at 13:26
  • If you prefer to directly generate points that are within the shape, this is definitely possible, but IMHO harder (it might just be a personal feeling, though). For instance, this question tackles the issue of uniformly generating points in a circle: http://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly. – Luc Touraille Jun 19 '12 at 13:28
  • If you want to generate a point within an arbitrary region in constant time, this will be very difficult. If you are happy to restrict your regions to be simple geometric shapes that are easily defined, like a square or circle. Is this what you want? Repeatedly generating random points and testing whether they are inside a given polygon is a vastly simpler process that can be applied to regions of any shape. – Rook Jun 19 '12 at 13:30

3 Answers3

2

First of all, instead of storing your coordinates in a vector, you would be better off using std::pair or a custom class:

struct Point
{
    int x;
    int y;
};

Then you just need to have a way of generating random points, such as

Point randomPoint(Point const & min, Point const & max)
{
    static std::mt19937 gen;
    std::uniform_int_distribution<> distribX(min.x, max.x);
    std::uniform_int_distribution<> distribY(min.y, max.y);

    return Point{distribX(gen), distribY(gen)};
}

You can then use this generation function to fill your vector, for instance with generate_n:

unsigned int const nbPoints = 100;

std::vector<Point> points;

std::generate_n(back_inserter(points), nbPoints, 
    std::bind(randomPoint, Point{0, 0}, Point{1000, 1000}));

Note that this will generate random points, so you are not guaranteed to end up with a square, a triangle, etc. If you want to generate a could, you could either use a non-uniform distribution (if you know what distribution your coordinates follow) to generate your numbers, or use rejection sampling to discard points that are not in the area you want them to be.

Generating a triangle boils down to drawing three random points.

To generate a square, you can draw two points, corresponding to two opposite corners of the square.

And so on... I don't think there is a "universal" solution that would work for any shapes.

Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
  • I'm assuming that the OP meant vector in the graphical or geometric sense rather than the `std::vector` sense. – Rook Jun 19 '12 at 12:14
  • @Rook: Oh, you must be right. Well, I think the first part of my post still answers that :). – Luc Touraille Jun 19 '12 at 12:16
  • But what I want is that the generated points will constitute a certain form: e.g. a cyrcle, or a square. – shn Jun 19 '12 at 12:19
  • @user995434: Then I draw your attention to my original comment on your question. – Rook Jun 19 '12 at 12:24
  • @Rook: I reformulate the question simply: How do I generate in C++ or Python, random points (x,y) following: a circular distribution, a square distribution, and a triangular distribution. I didn't understood what you mean by draw_cross – shn Jun 19 '12 at 12:43
  • Ahh, I misunderstood your original question. I think i understand now. – Rook Jun 19 '12 at 12:49
  • @user995434: I am afraid I misunderstood the question as well. – Tommy Andersen Jun 19 '12 at 12:57
  • @TommyA well I've gave a simple example for the square shape in my first post. I just want to do the same for cycle, for triangle, and the a cloud like http://3.bp.blogspot.com/_k1D0z3ucw7o/SITL8Et0QAI/AAAAAAAADSw/Bp_N8c9i5SE/s320/Sigma0.25.png – shn Jun 19 '12 at 13:14
1

As supplement to Luc Touraille's post.

For a square find two random points and let these two points be the two furhest apart corners of the square.

For a triangle find three random points and let the triangle be triangle these three points make.

For a circle find a random point as a center for the circle and another random point, and let the distance between the two be the radius of the circle.

A more general approach could be to find the center point of the figures and let the parameters (scale, rotation, etc.) be found by further randomly generated numbers. (I guess a bit like Rook suggests).

Tommy Andersen
  • 7,165
  • 1
  • 31
  • 50
0

Your problem is underspecified.

There is no such thing as a "circular distribution" or "triangular distribution".

You probably meant: a uniform distribution in the shape of a circle, rectangle, triangle. There even is no uniquely specified triangle...

The key point is uniform.

E.g. a standard normal distribution in 2D may appear to be somewhat circular, but it is not exactly the shape of a circle.

There is no random generator that directly produces a circle with uniform density; at least not that I know of. The most common way is just to generate a square, and reject those points that you do not want to have.

E.g. generate (x,y) pairs on [0:1]x[0:1] and reject those with distance from .5,.5 larger than .5 - then you get the circle.

If you - as other users suggested - generate a radius and a distance, then the generated points will not be uniformly distributed on the circle.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194