import {Plot} from "@observablehq/plot"
import {slider} from "@jashkenas/inputs"
N = 1000
unit_triangle = [
{x: 0, y: 0},
{x: 1, y: 0},
{x: 0, y: 1},
{x: 0, y: 0}
]
equilateral_triangle = [
{x: 0, y: 0},
{x: 1, y: 0},
{x: 0.5, y: Math.sqrt(3) / 2},
{x: 0, y: 0}
]
// Generate N random points in the unit square
// and label them as "Inside" or "Reflected points"
random_points = Array.from({length: N}, () => {
let x = Math.random();
let y = Math.random();
if (x + y <= 1) {
return {x, y, label: "Inside"};
} else {
return {x, y, label: "Reflected points"};
}
});
// Reflect the points across the midpoint of the hypotenuse
unit_triangle_points = random_points.map(d => {
if (d.label === "Reflected points") {
return {x: 1 - d.x, y: 1 - d.y, label: d.label};
} else {
return d;
}
});
// Transform the points to the equilateral triangle using barycentric coordinates
transformed_points = unit_triangle_points.map(d => {
const A = equilateral_triangle[0];
const B = equilateral_triangle[1];
const C = equilateral_triangle[2];
return {
x: d.x * A.x + d.y * B.x + (1 - d.x - d.y) * C.x,
y: d.x * A.y + d.y * B.y + (1 - d.x - d.y) * C.y,
label: d.label
};
});
Random points in a triangle
randomness
triangles
barycentric coordinates
Randomness is a surprisingly hard thing to simulate. Any program, by definition, has a predictable output. The best you can hope for is to predictably generate points that look random (pseudo-random) and fool some statistical tests. All random generation relies on two things:
- A pseudo-random number generator that outputs a stream of numbers that “looks random”
- A mathematical function that converts uniform random variable(s) into random variables with other distributions
Mathematicians are mostly interested in engineering Step 2. Step 1 is important but is usually delegated to computer engineers.
With that preamble, here’s the question: Generate points randomly inside a triangle. I need this in order to play around with Sperner’s lemma examples.
The first step is to generate random points in the “standard triangle” with vertices \([0, 0], [1, 0], [0, 1]\). A very simple trick for this is to generate points in the unit square and “reflect the points” across the midpoint of the hypotenuse, \([0.5, 0.5]\).
Next, we use the barycentric transformation to transform the standard triangle into the desired triangle—in the example above, the equilateral triangle with vertices \([0, 0], [1, 0], [0.5, \sqrt{3}/2]\).
Back to top