Reputation: 9424
I'd like to generate random points within a triangle based on the points (0, 0) (0, 1), (1, 0.5)
. I figure the easiest way to do this is to generate the points within the (0, 0), (0, 1), (1, 1), (1, 0)
square using numpy and then filter it to that triangle.
Here is the code that will generate the points within that square.
pts = np.random.rand(1000, 2)
However, I'm not sure how to filter the numpy array to only the points within that triangle.
Upvotes: 0
Views: 262
Reputation: 77857
I'm going to try a multi-pronged answer for the unresolved contingencies:
If you don't need a uniform distribution, then simply generate the x-coord uniformly from [0, 1], then generate the y-coord from [0.5-((1-x)/2), 0.5+((1-x)/2)] (yes, you can simplify those expressions). This makes each x-coordinate equally likely, and therefore favors points with fewer corresponding y-coordinates: points near the apex of your triangle will get chosen more often than those near the base.
You can correct this with the inverse transformation on your x-coordinate: square x
before you choose y.
If you need to use the points you already generated, then you have no choice but to filter them in some fashion. Half of them will be unsuitable, with those points randomly distributed through your array. There is no way to slice the array to achieve that result.
EDIT CREDIT to Scott Hunter
However, you can filter and transform the unsuitable points: map them with a simple transformation from outside the triangle to inside. Your triangle is bounded above by the lines
y = 2x
y = -2x + 2
A simple mapping is to reflect each point above these lines, across the midpoint of the line segment: either (0.25, 0.5) or (0.75, 0.5). This is a simple equation: to reflect point (x, y)
across point (a, b)
, the reflection is (2a-x, 2b-y)
.
Upvotes: 1
Reputation: 206
If you want to go for a filtering approach, you have to find a condition to check which points are inside the triangle. Then you can use numpys argwhere function to find the indices of all points that fullfill your condition:
pts = np.random.rand(1000, 2)
x_coord = pts[:, 0]
y_coord = pts[:, 1]
def _in_triangle(x, y):
# You might want to doublecheck if this condition is correct, I am sure there is a better way.
return (((x <= 0.5) & (y <= 2*x)) | ((x <= 0.5) & (y <= 2-2*x))) & (0 <= x) & (x <= 1) & (0 <= y) & (y <= 1)
points_in_triangle = pts[np.argwhere(_in_triangle(x_coord, y_coord))]
Upvotes: 2