メインコンテンツまでスキップ

voronoi: Voronoi Diagram Generation

Cellular Pattern Construction Through Distance Analysis

Voronoi diagrams partition space into regions based on proximity to seed points. Each region contains all points closer to its seed than to any other seed, creating natural cellular patterns found in biology, geology, and architecture.

Mathematical Foundation

The Voronoi diagram construction follows these principles:

  1. Seed Point Distribution: Random points pip_i distributed across a grid
  2. Distance Calculation: For any point qq, compute distances di=qpid_i = ||q - p_i||
  3. Region Assignment: Assign qq to region ii where di=min(d1,d2,...,dn)d_i = \min(d_1, d_2, ..., d_n)
  4. Boundary Formation: Boundaries occur where di=djd_i = d_j for distinct seeds

The distance metric typically uses Euclidean distance: d(q,pi)=(qxpi,x)2+(qypi,y)2d(q, p_i) = \sqrt{(q_x - p_{i,x})^2 + (q_y - p_{i,y})^2}

Function Variants

FunctionInputOutputPurpose
voronoivec2, floatvec3Time-animated Voronoi
voronoiVec2vec2vec3Static 2D Voronoi
voronoiVec3vec3vec33D coordinates as time

Return Value Structure

The functions return vec3(seed_x, seed_y, distance) where:

  • x, y: Coordinates of the nearest seed point
  • z: Distance to the nearest seed point

Implementation Examples

ライブエディター
const fragment = () => {
      const p = uv.mul(12)
      const cell = voronoiVec2(p)
      const borders = smoothstep(0, 0.05, cell.z)
      const cellId = cell.xy.dot(vec2(12.9898, 78.233))
      const cellColor = vec3(
              cellId.sin().mul(0.5).add(0.5),
              cellId.mul(2.1).sin().mul(0.5).add(0.5),
              cellId.mul(3.3).sin().mul(0.5).add(0.5)
      )
      return vec4(cellColor.mul(borders), 1)
}
ライブエディター
const fragment = () => {
      const baseScale = 8
      const p = uv.mul(baseScale)
      const time = iTime.mul(0.2)

      const cell1 = voronoi(p, time)
      const cell2 = voronoi(p.mul(2), time.mul(1.3))

      const distortion = cell1.z.sub(cell2.z).mul(2)
      const ripples = cell1.z.mul(40).sub(time.mul(8)).sin().mul(0.1)

      const intensity = distortion.add(ripples).clamp(0, 1)
      const hue = vec2(0.5, 0.8).dot(cell1.xy).add(time.mul(0.1))

      const r = hue.mul(6.28).sin().mul(0.5).add(0.5)
      const g = hue.mul(6.28).add(2.09).sin().mul(0.5).add(0.5)
      const b = hue.mul(6.28).add(4.19).sin().mul(0.5).add(0.5)

      return vec4(vec3(r, g, b).mul(intensity), 1)

}