パーリンノイズのジェネレータを試しに書いています。
(内部に時間を持たせたものに改良中)
単純に2次元に展開しただけだとブラウン運動に近いかな?(青線)
複合するとなんとなくよさげ。(赤線)
js
1<!DOCTYPE html>
2<meta charset="utf-8">
3<title></title>
4<style>
5</style>
6
7<body>
8<canvas width="1000" height="900"></canvas>
9
10<script>
11
12class P2{
13 constructor(x=0,y=0){this.x=x;this.y=y}
14 toArray(){return[this.x,this.y]}//単純配列化
15 clone(){return new this.constructor(this.x, this.y)}//複写
16 add({x=0,y=0},{x:X,y:Y}=this){this.x=X+x;this.y=Y+y;return this}//加算
17}
18
19//パーリンノイズ
20class PerlinNoise {
21 constructor (range = 1, pitch = .01) {
22 this.pitch = pitch;
23 this.range = range;
24 this.cnt = 0;
25 this.begin = this.nextRandom;
26 this.end = this.nextRandom;
27 }
28
29 get nextRandom () {
30 return (Math.random () -.5) * this.range;
31 }
32
33 valueOf () {
34 if (1 < (this.cnt += this.pitch))
35 [this.cnt, this.begin, this.end] = [0, this.end, this.nextRandom];
36
37 let
38 r0 = this.cnt,
39 u = r0 * this.begin,
40 v = (r0 - 1) * this.end,
41 st = r0 **2 * (3 - 2 * r0);
42
43 return 2 * (u + st * (v - u));
44 }
45
46 clone (n = 1, m = n) {
47 return new this.constructor (this.range * n, this.pitch * m);
48 }
49}
50
51
52//パーリンノイズを複合したオブジェクト
53class compositePerlinNoise {
54 constructor (...pns) {
55 this.pns = pns;
56 }
57
58 clone (n = 1, m = n) {
59 return new this.constructor (...this.pns.map (ps=> ps.clone (m, n)));
60 }
61
62 valueOf () {
63 return this.pns.reduce ((a,b)=> a + b, 0);
64 }
65
66 static create (...param) {
67 return new this (...param.map (args=> new PerlinNoise (...args)))
68 }
69}
70
71//二次元に拡張したパーリンノイズ
72class PerlinNoise2D {
73 constructor (...args) {
74 this.args = args;
75 }
76 get x () { return this.args[0]; }
77 get y () { return this.args[1]; }
78
79 static create (...param) {
80 let
81 pnx = compositePerlinNoise.create (...param),
82 pny = pnx.clone ();
83
84 return new this (pnx, pny);
85 }
86}
87
88
89class Canvas {
90
91 constructor (canvas = document.querySelector ('canvas')) {
92 this.canvas = canvas;
93 this.ctx = canvas.getContext ('2d');
94 }
95
96 static create (canvas = document.querySelector ('canvas')) {
97 let obj = new this (canvas);
98 return obj.cls ();
99 }
100
101 cls () {
102 // let {width, height}=this.canvas; this.ctx.clearRect(0,0,width,height);
103 this.canvas.width = this.canvas.width;
104 return this;
105 }
106
107 line (p0, p1, color = 'rgba(200,0,0,.5)', width = 1) {
108 let ctx = this.ctx;
109 ctx.beginPath ();
110 ctx.strokeStyle = color;
111 ctx.lineWidth = width;
112 ctx.moveTo (p0.x, p0.y);
113 ctx.lineTo (p1.x, p1.y);
114 ctx.closePath ();
115 ctx.stroke ();
116 return this;
117 }
118}
119
120//__________________________
121
122
123let
124 cg = Canvas.create (),
125 prm0 = [[4,.002], [4,.004], [4, .005]],
126 pn0 = PerlinNoise2D.create (...prm0),
127 p0a = new P2 (500,400), p0b,
128
129 pn1 = PerlinNoise2D.create ([8,.005]),
130 p1a = new P2 (500,400), p1b;
131
132
133function demo () {
134 p0b = p0a.clone(); p0a.add (pn0); cg.line (p0a, p0b, 'rgba(255,0,0,.1)', 10);
135 p1b = p1a.clone(); p1a.add (pn1); cg.line (p1a, p1b, 'rgba(0,0,255,.2)', 10);
136 requestAnimationFrame (demo);
137}
138
139demo ();
140
141
142</script>