feat(package): voronoi: simple voronoi algoritm realization

This commit is contained in:
2025-11-14 15:51:28 +00:00
parent 6204ba5abb
commit 5a8fd0a275
6 changed files with 142 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
```sh
sh voronoi.sh 500 500 65 "$(sh ./gen-voronoi-points.sh 400 0 0 500 0 0 500)" 0,0,255 255,0,0 \
| magick -size 200x200 xc:white -draw @- voronoi.png
```

View File

@@ -0,0 +1,17 @@
#!/bin/sh
# posix: uniform points in a 2D parallelogram for Voronoi seeds
# usage: ./gen N x0 y0 ax ay bx by
# generates N points p = (x0,y0) + u*(ax,ay) + v*(bx,by), with u,v ~ U[0,1)
[ "$#" -eq 7 ] || { echo "usage: $0 N x0 y0 ax ay bx by" >&2; exit 1; }
awk -v n="$1" -v x0="$2" -v y0="$3" -v ax="$4" -v ay="$5" -v bx="$6" -v by="$7" '
BEGIN{
srand();
for(i=0;i<n;i++){
u = rand(); v = rand();
x = int(x0 + u*ax + v*bx);
y = int(y0 + u*ay + v*by);
printf "%d,%d ", x, y;
}
}'

View File

@@ -0,0 +1,49 @@
function clamp(v){ return v<0?0:(v>1?1:v) }
function color_lerp(p, q, r1, g1, b1, r2, g2, b3, x){
t = (x - p) / (q - p)
t = clamp(t)
r = int(r1 + t*(r2 - r1) + 0.5)
g = int(g1 + t*(g2 - g1) + 0.5)
b = int(b1 + t*(b2 - b1) + 0.5)
return sprintf("#%02X%02X%02X", r, g, b)
}
BEGIN {
# external variables
# PTS is voronoi centers
# W is canvas width
# H is canvas height
# FADE is fade max distance
# C1 is first color in gradient
# C2 is secont color in gradient
if (C1 == "") C1 = "0,0,0"
if (C2 == "") C2 = "255,255,255"
split(C1, c1, ",")
split(C2, c2, ",")
n = split(PTS, pairs, " ")
for (i = 1; i <= n; ++i) {
split(pairs[i], xy, ",")
px[i] = xy[1] + 0
py[i] = xy[2] + 0
}
for (y = 0; y < H; y++)
for (x = 0; x < W; x++) {
min_d = 1e308
for (i = 1; i <= n; i++) {
dx = x - px[i]
dy = y - py[i]
d = sqrt(dx*dx + dy*dy)
if (d < min_d)
min_d = d
}
fade = FADE - min_d
if (fade < 0) fade = 0
color = color_lerp(0, FADE, c1[1],c1[2],c1[3], c2[1],c2[2],c2[3], fade)
printf "fill %s point %d,%d\n", color, x, y
}
}

View File

@@ -0,0 +1,49 @@
#define PTS_N 500
#define
// Author @patriciogv - 2015
// http://patriciogonzalezvivo.com
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
float random (vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898,78.233)))*43758.5453123);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 st = gl_FragCoord.xy/u_resolution.xy;
float rnd = random( st );
for(i=0;i<PTS_N;i++){
u = rnd(); v = rnd();
x = int(x0 + u*ax + v*bx);
y = int(y0 + u*ay + v*by);
printf "%d,%d ", x, y;
}
min_d = 1e308
for (i = 1; i <= n; i++) {
dx = x - px[i]
dy = y - py[i]
d = sqrt(dx*dx + dy*dy)
if (d < min_d)
min_d = d
}
fade = FADE - min_d
if (fade < 0) fade = 0
color = color_lerp(0, FADE, c1[1],c1[2],c1[3], c2[1],c2[2],c2[3], fade)
printf "fill %s point %d,%d\n", color, x, y
//gl_FragColor = vec4(vec3(rnd),1.0);
}

BIN
package/voronoi/voronoi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -0,0 +1,23 @@
#!/bin/sh
# Usage: ./voronoi_data.sh WIDTH HEIGHT "x1,y1 x2,y2 ..."
if [ $# -lt 4 ]; then
printf 'Usage: %s WIDTH HEIGHT FADE "x1,y1 x2,y2 ..."\n' "$0" >&2
exit 1
fi
W=$1
H=$2
FADE=$3
PTS=$4
C1=$5
C2=$6
awk \
-v W="$W" \
-v H="$H" \
-v PTS="$PTS" \
-v FADE="$FADE" \
-v C1="$C1" \
-v C2="$C2" \
-f ./voronoi.awk